Initial work on dereferencing by path
diff --git a/remote-content-api/content-mapper/pom.xml b/remote-content-api/content-mapper/pom.xml
index 98d45e6..0bca90c 100644
--- a/remote-content-api/content-mapper/pom.xml
+++ b/remote-content-api/content-mapper/pom.xml
@@ -74,6 +74,11 @@
       <scope>provided</scope>
     </dependency>
     <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
       <groupId>org.apache.sling</groupId>
       <artifactId>org.apache.sling.api</artifactId>
       <version>2.18.4</version>
diff --git a/remote-content-api/content-mapper/src/main/java/org/apache/sling/contentmapper/api/AnnotationNames.java b/remote-content-api/content-mapper/src/main/java/org/apache/sling/contentmapper/api/AnnotationNames.java
index 5508348..045c5c6 100644
--- a/remote-content-api/content-mapper/src/main/java/org/apache/sling/contentmapper/api/AnnotationNames.java
+++ b/remote-content-api/content-mapper/src/main/java/org/apache/sling/contentmapper/api/AnnotationNames.java
@@ -31,4 +31,5 @@
     String CONTENT_INCLUDE_PROPERTY_REGEXP = SLING_PREFIX + "includePropertyRegexp";
     String CONTENT_EXCLUDE_PROPERTY_REGEXP = SLING_PREFIX + "excludePropertyRegexp";
     String NAVIGATION_PROPERTIES_LIST = SLING_PREFIX + "navigationPropertiesList";
+    String DEREFERENCE_BY_PATH = SLING_PREFIX + "dereferenceByPath";
 }
\ No newline at end of file
diff --git a/remote-content-api/content-mapper/src/main/java/org/apache/sling/contentmapper/impl/ContentContentMapper.java b/remote-content-api/content-mapper/src/main/java/org/apache/sling/contentmapper/impl/ContentContentMapper.java
index de84ac9..20c4794 100644
--- a/remote-content-api/content-mapper/src/main/java/org/apache/sling/contentmapper/impl/ContentContentMapper.java
+++ b/remote-content-api/content-mapper/src/main/java/org/apache/sling/contentmapper/impl/ContentContentMapper.java
@@ -20,6 +20,7 @@
 package org.apache.sling.contentmapper.impl;
 
 import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ValueMap;
 import org.apache.sling.contentmapper.api.ContentMapper;
 import org.apache.sling.contentmapper.api.MappingTarget;
 import org.apache.sling.experimental.typesystem.Type;
@@ -27,15 +28,20 @@
 import org.jetbrains.annotations.NotNull;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import static org.apache.sling.contentmapper.api.AnnotationNames.VISIT_CONTENT;
 import static org.apache.sling.contentmapper.api.AnnotationNames.DOCUMENT_ROOT;
 import static org.apache.sling.contentmapper.api.AnnotationNames.VISIT_CONTENT_RESOURCE_NAME_PATTERN;
 
+import static org.apache.sling.contentmapper.api.AnnotationNames.DEREFERENCE_BY_PATH;
+
 @Component(service = ContentMapper.class, property = { ContentMapper.ROLE + "=content" })
 public class ContentContentMapper implements ContentMapper {
 
     private final PropertiesMapper propertiesMapper = new PropertiesMapper();
+    private final Logger log = LoggerFactory.getLogger(getClass());
 
     @Reference
     private TypeSystem typeSystem;
@@ -50,10 +56,29 @@
 
     private void mapResource(@NotNull Resource r, @NotNull MappingTarget.TargetNode dest, 
         UrlBuilder urlb, Type parentType, ContentPropertiesSelector selector, boolean recurse) {
+
+        log.debug("Mapping Resource {} as {}", r.getPath(), r.getResourceType());
         propertiesMapper.mapProperties(dest, r, selector);
 
+        // Dereference by path if specified
+        // TODO detect cycles which might lead to infinite loops
+        final String derefPathPropertyName = TypeUtil.getAnnotationValue(parentType, DEREFERENCE_BY_PATH);
+        if(derefPathPropertyName != null) {
+            log.debug("Dereferencing {} on {}", r.getPath(), derefPathPropertyName);
+            final ValueMap vm = r.adaptTo(ValueMap.class);
+            final String derefPath = vm == null ? null : vm.get(derefPathPropertyName, String.class);
+            if(derefPath != null) {
+                final Resource dereferenced = r.getResourceResolver().getResource(derefPath);
+                if(dereferenced != null) {
+                    final MappingTarget.TargetNode derefNode = dest.addChild("dereferenced_by_" + derefPathPropertyName);
+                    mapResource(dereferenced, derefNode, urlb, parentType, selector, recurse);
+                }
+            }
+        }
+
         // TODO detect too much recursion?
         if(recurse) {
+            log.debug("Recursing into {}", r.getPath());
             final String namePattern = TypeUtil.getAnnotationValue(parentType, VISIT_CONTENT_RESOURCE_NAME_PATTERN);
             for(Resource child : r.getChildren()) {
                 if(namePattern != null && !child.getName().equals(namePattern)) {
@@ -65,6 +90,8 @@
                     mapResource(child, childDest, urlb, childType, selector, true);
                 }
             }
+        } else if(log.isDebugEnabled()) {
+            log.debug("NOT recursing into {}", r.getPath());
         }
     }
 }
\ No newline at end of file
diff --git a/remote-content-api/sample-app/src/main/java/org/apache/sling/remotecontentapi/typesystem/HardcodedTypeSystem.java b/remote-content-api/sample-app/src/main/java/org/apache/sling/remotecontentapi/typesystem/HardcodedTypeSystem.java
index ed9175c..c8e37ae 100644
--- a/remote-content-api/sample-app/src/main/java/org/apache/sling/remotecontentapi/typesystem/HardcodedTypeSystem.java
+++ b/remote-content-api/sample-app/src/main/java/org/apache/sling/remotecontentapi/typesystem/HardcodedTypeSystem.java
@@ -36,6 +36,7 @@
 import static org.apache.sling.contentmapper.api.AnnotationNames.CONTENT_EXCLUDE_PROPERTY_REGEXP;
 import static org.apache.sling.contentmapper.api.AnnotationNames.CONTENT_INCLUDE_PROPERTY_REGEXP;
 import static org.apache.sling.contentmapper.api.AnnotationNames.NAVIGATION_PROPERTIES_LIST;
+import static org.apache.sling.contentmapper.api.AnnotationNames.DEREFERENCE_BY_PATH;
 
 /** Temporary hardcoded type system for this prototype, until we
  *  have the actual type system
@@ -86,6 +87,15 @@
             Builder.forResourceType("wknd/components/page")
             .withAnnotation(VISIT_CONTENT, TRUE)
         );
+        addType(
+            Builder.forResourceType("wknd/components/image")
+            .withAnnotation(VISIT_CONTENT, TRUE)
+            .withAnnotation(DEREFERENCE_BY_PATH, "fileReference")
+        );
+        addType(
+            Builder.forResourceType("wknd/components/carousel")
+            .withAnnotation(VISIT_CONTENT, TRUE)
+        );
 
         // for /content/articles examples
         addType(
diff --git a/remote-content-api/sample-app/src/main/resources/features/feature-remote-content-api.json b/remote-content-api/sample-app/src/main/resources/features/feature-remote-content-api.json
index eed95fc..62ee7c6 100644
--- a/remote-content-api/sample-app/src/main/resources/features/feature-remote-content-api.json
+++ b/remote-content-api/sample-app/src/main/resources/features/feature-remote-content-api.json
@@ -1,7 +1,7 @@
 {
   "id":"org.apache.sling:org.apache.sling.dokapi:slingosgifeature:sling12:0.0.1-SNAPSHOT",
-  "title":"Apache Sling Dokapi Testing",
-  "description":"Demo website for dokapi API",
+  "title":"Apache Sling Remote Content API Sample App",
+  "description":"Demonstrates the Remote Content API",
   "vendor":"The Apache Software Foundation",
   "license":"Apache License, Version 2.0",
   "variables":{},
@@ -21,7 +21,7 @@
       ],
       "whitelist.name":"installer-packages"
     },
-    "org.apache.sling.commons.log.LogManager.factory.config~debug.log" : {
+    "org.apache.sling.commons.log.LogManager.factory.config~info.log" : {
       "org.apache.sling.commons.log.file": "logs/debug.log",
       "org.apache.sling.commons.log.level": "INFO",
       "org.apache.sling.commons.log.names":
@@ -34,6 +34,15 @@
           "org.apache.sling.scripting"
         ],
       "org.apache.sling.commons.log.pattern": "%-5level [%-50logger{50}] %message ## %mdc{sling.InternalRequest} %n"
+    },
+    "org.apache.sling.commons.log.LogManager.factory.config~debug.log" : {
+      "org.apache.sling.commons.log.file": "logs/debug.log",
+      "org.apache.sling.commons.log.level": "DEBUG",
+      "org.apache.sling.commons.log.names":
+        [
+          "org.apache.sling.contentmapper"
+        ],
+      "org.apache.sling.commons.log.pattern": "%-5level [%-50logger{50}] %message ## %mdc{sling.InternalRequest} %n"
     }
   }
 }
\ No newline at end of file