Refactored 
diff --git a/moxy/dynamic/flickr/src/main/java/eclipselink/example/moxy/dynamic/flickr/AlchemyAccessor.java b/moxy/dynamic/flickr/src/main/java/eclipselink/example/moxy/dynamic/flickr/AlchemyAccessor.java
new file mode 100644
index 0000000..b49fa7e
--- /dev/null
+++ b/moxy/dynamic/flickr/src/main/java/eclipselink/example/moxy/dynamic/flickr/AlchemyAccessor.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ *
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ ******************************************************************************/
+package eclipselink.example.moxy.dynamic.flickr;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.StringTokenizer;
+
+import com.likethecolor.alchemy.api.Client;
+import com.likethecolor.alchemy.api.call.RankedConceptsCall;
+import com.likethecolor.alchemy.api.call.type.CallTypeText;
+import com.likethecolor.alchemy.api.entity.ConceptAlchemyEntity;
+import com.likethecolor.alchemy.api.entity.Response;
+import com.likethecolor.alchemy.api.params.ConceptParams;
+
+public class AlchemyAccessor {
+
+    /**
+     * This method uses the AlchemyAPI web service to determine the "concepts"
+     * contained in the headline. It does not use EclipseLink and is used solely
+     * for the purpose of this example application.
+     * 
+     * @see <a href="http://www.alchemyapi.com">AlchemyAPI</a>
+     */
+    @SuppressWarnings("unchecked")
+    public String extractConcepts(String postTitle) {
+        try {
+            Client client = new Client(ALCHEMY_KEY);
+
+            ConceptParams params = new ConceptParams();
+            params.setMaxRetrieve(ALCHEMY_CONCEPTS_TO_RETURN);
+
+            CallTypeText callType = new CallTypeText(postTitle);
+            RankedConceptsCall call = new RankedConceptsCall(callType, params);
+            Response<ConceptAlchemyEntity> response = client.call(call);
+
+            String concepts = "";
+
+            Iterator<ConceptAlchemyEntity> it = response.iterator();
+            if (!it.hasNext()) {
+                // If Alchemy didn't find any concepts, use string length
+                // algorithm
+                return extractKeywords(postTitle);
+            } else {
+                while (it.hasNext()) {
+                    ConceptAlchemyEntity alchemyEntity = it.next();
+                    concepts += alchemyEntity.getConcept();
+                    if (it.hasNext()) {
+                        concepts += ",";
+                    }
+                }
+            }
+
+            concepts = concepts.replace(" ", "+");
+
+            return concepts;
+        } catch (Exception e) {
+            return extractKeywords(postTitle);
+        }
+    }
+
+    private String extractKeywords(String postTitle) {
+        StringTokenizer tokenizer = new StringTokenizer(postTitle, ",.!?()[]'\"- \t\n\r\f");
+
+        ArrayList<String> words = new ArrayList<String>();
+
+        while (tokenizer.hasMoreElements()) {
+            words.add(tokenizer.nextToken());
+        }
+
+        // Sort words, longest one first
+        Collections.sort(words, new StringLengthComparator());
+
+        String keywords = null;
+        if (words.size() > 1) {
+            keywords = words.get(0) + "," + words.get(1);
+        } else {
+            keywords = words.get(0);
+        }
+
+        return keywords;
+    }
+
+    private class StringLengthComparator implements Comparator<String> {
+        public int compare(String o1, String o2) {
+            if (o1.length() > o2.length()) {
+                return -1;
+            } else if (o1.length() < o2.length()) {
+                return 1;
+            } else {
+                return 0;
+            }
+        }
+    }
+
+    private final int ALCHEMY_CONCEPTS_TO_RETURN = 2;
+    private final String ALCHEMY_KEY = "/META-INF/a.key";
+
+}
\ No newline at end of file
diff --git a/moxy/dynamic/flickr/src/main/java/eclipselink/example/moxy/dynamic/flickr/FlikrReader.java b/moxy/dynamic/flickr/src/main/java/eclipselink/example/moxy/dynamic/flickr/FlikrReader.java
new file mode 100644
index 0000000..d518d9e
--- /dev/null
+++ b/moxy/dynamic/flickr/src/main/java/eclipselink/example/moxy/dynamic/flickr/FlikrReader.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ *
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ ******************************************************************************/
+package eclipselink.example.moxy.dynamic.flickr;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+
+import org.eclipse.persistence.dynamic.DynamicEntity;
+import org.eclipse.persistence.jaxb.JAXBContextProperties;
+import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
+import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContextFactory;
+
+public class FlikrReader {
+
+    private DynamicJAXBContext context;
+
+    public FlikrReader() {
+        ClassLoader loader = Thread.currentThread().getContextClassLoader();
+
+        InputStream flickrBindings = loader.getResourceAsStream(FLICKR_BINDINGS);
+
+        ArrayList<InputStream> dataBindings = new ArrayList<InputStream>(3);
+        dataBindings.add(flickrBindings);
+
+        Map<String, Object> properties = new HashMap<String, Object>();
+        properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, dataBindings);
+        try {
+            context = DynamicJAXBContextFactory.createContextFromOXM(loader, properties);
+        } catch (JAXBException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+
+    }
+
+    public Map<Object, DynamicEntity> readFlickrResults(Map<Object, DynamicEntity> redditMap) throws Exception {
+        Map<Object, DynamicEntity> results = new HashMap<Object, DynamicEntity>();
+        
+        for (Object postUrl : redditMap.keySet()) {
+            DynamicEntity post = redditMap.get(postUrl);
+
+            System.out.println();
+            System.out.println("Headline: [" + post.get("title") + "]");
+
+            String keywords = new AlchemyAccessor().extractConcepts(post.get("title").toString());
+
+            String flickrUrlString = FLICKR_URL + keywords;
+            System.out.print("Searching Flickr: [" + flickrUrlString + "]... ");
+            InputStream flickrStream = new URL(flickrUrlString).openConnection().getInputStream();
+            System.out.println("Done.");
+
+            Unmarshaller u = context.createUnmarshaller();
+            DynamicEntity flickrResults = (DynamicEntity) u.unmarshal(flickrStream);
+
+            results.put(postUrl, flickrResults);
+
+            ArrayList<DynamicEntity> flickerItems = flickrResults.get("items");
+            if (flickerItems != null) {
+                int size = flickerItems.size();
+                if (size >= IMAGE_LIMIT) {
+                    size = IMAGE_LIMIT;
+                }
+                for (int i = 0; i < size; i++) {
+                    System.out.println("\t" + flickerItems.get(i).get("imageUrl"));
+                }
+            } else {
+                System.out.println("\tNo results found.");
+            }
+        }
+        
+        return results;
+    }
+
+    // ========================================================================
+
+    // See http://www.flickr.com/services/feeds/
+    private final int IMAGE_LIMIT = 6;
+    private final String FLICKR_URL = "http://api.flickr.com/services/feeds/photos_public.gne?safe_search=1&tags=";
+    private final String FLICKR_BINDINGS = "META-INF/bindings-flickr.json";
+
+}
\ No newline at end of file
diff --git a/moxy/dynamic/flickr/src/main/java/eclipselink/example/moxy/dynamic/flickr/HTMLWriter.java b/moxy/dynamic/flickr/src/main/java/eclipselink/example/moxy/dynamic/flickr/HTMLWriter.java
new file mode 100644
index 0000000..4440e71
--- /dev/null
+++ b/moxy/dynamic/flickr/src/main/java/eclipselink/example/moxy/dynamic/flickr/HTMLWriter.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ *
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ ******************************************************************************/
+package eclipselink.example.moxy.dynamic.flickr;
+
+import java.awt.Desktop;
+import java.io.File;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+
+import org.eclipse.persistence.dynamic.DynamicEntity;
+import org.eclipse.persistence.jaxb.JAXBContextProperties;
+import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
+import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContextFactory;
+
+public class HTMLWriter {
+
+    private DynamicJAXBContext context;
+
+    private File outputFile;
+
+    public HTMLWriter() {
+        ClassLoader loader = Thread.currentThread().getContextClassLoader();
+
+        InputStream htmlBindings = loader.getResourceAsStream(HTML_BINDINGS);
+
+        ArrayList<InputStream> dataBindings = new ArrayList<InputStream>(3);
+        dataBindings.add(htmlBindings);
+
+        Map<String, Object> properties = new HashMap<String, Object>();
+        properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, dataBindings);
+        try {
+            context = DynamicJAXBContextFactory.createContextFromOXM(loader, properties);
+        } catch (JAXBException e) {
+            throw new RuntimeException("Context creation failed", e);
+        }
+
+        outputFile = new File("output.html");
+    }
+
+    public void write(String topic, int imageLimit, Map<Object, DynamicEntity> redditMap, Map<Object, DynamicEntity> flickrMap) throws Exception {
+        DynamicEntity html = context.newDynamicEntity("eclipselink.example.moxy.dynamic.flickr.HtmlPage");
+        html.set("title", "EclipseLink MOXy - Dynamic JAXB");
+        html.set("css", "style.css");
+        html.set("rel", "stylesheet");
+        html.set("type", "text/css");
+        html.set("media", "screen");
+
+        DynamicEntity body = context.newDynamicEntity("eclipselink.example.moxy.dynamic.flickr.HtmlBody");
+        body.set("title", "Reddit /" + topic + " - Today's Top Posts");
+
+        ArrayList<DynamicEntity> divs = new ArrayList<DynamicEntity>();
+
+        for (Object postUrl : redditMap.keySet()) {
+            DynamicEntity post = redditMap.get(postUrl);
+            DynamicEntity flickrResults = flickrMap.get(postUrl);
+
+            // Article Link
+            // ================================================================
+
+            DynamicEntity redditDiv = context.newDynamicEntity("eclipselink.example.moxy.dynamic.flickr.HtmlDiv");
+            redditDiv.set("id", "redditPost");
+
+            ArrayList<DynamicEntity> divContent = new ArrayList<DynamicEntity>();
+
+            DynamicEntity redditLink = context.newDynamicEntity("eclipselink.example.moxy.dynamic.flickr.HtmlTextLink");
+            redditLink.set("url", post.get("url"));
+            redditLink.set("title", post.get("title"));
+            divContent.add(redditLink);
+
+            redditDiv.set("span", divContent);
+
+            // Flickr description and images
+            // ================================================================
+
+            DynamicEntity flickrDiv = context.newDynamicEntity("eclipselink.example.moxy.dynamic.flickr.HtmlDiv");
+            flickrDiv.set("id", "flickrResults");
+
+            divContent = new ArrayList<DynamicEntity>();
+
+            DynamicEntity flickrDescription = context.newDynamicEntity("eclipselink.example.moxy.dynamic.flickr.HtmlText");
+            flickrDescription.set("text", flickrResults.get("description"));
+            divContent.add(flickrDescription);
+
+            ArrayList<DynamicEntity> flickrItems = flickrResults.get("items");
+
+            int counter = 0;
+            if (flickrItems != null) {
+                Collections.shuffle(flickrItems, new Random(System.nanoTime()));
+                for (DynamicEntity flickrItem : flickrItems) {
+                    DynamicEntity flickrImageLink = context.newDynamicEntity("eclipselink.example.moxy.dynamic.flickr.HtmlImageLink");
+                    flickrImageLink.set("url", flickrItem.get("flickrPage"));
+                    flickrImageLink.set("image", flickrItem.get("imageUrl"));
+                    flickrImageLink.set("height", HTML_IMAGE_HEIGHT);
+                    divContent.add(flickrImageLink);
+                    counter++;
+                    if (counter == imageLimit) {
+                        break;
+                    }
+                }
+            } else {
+                DynamicEntity noneText = context.newDynamicEntity("eclipselink.example.moxy.dynamic.flickr.HtmlText");
+                noneText.set("text", "No results found.");
+                divContent.add(noneText);
+            }
+            flickrDiv.set("span", divContent);
+
+            divs.add(redditDiv);
+            divs.add(flickrDiv);
+        }
+
+        body.set("divs", divs);
+
+        html.set("body", body);
+
+        Marshaller m = context.createMarshaller();
+        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
+        m.setProperty(Marshaller.JAXB_FRAGMENT, true);
+        m.marshal(html, outputFile);
+    }
+
+    public void launchSystemBrowser() {
+        try {
+            Desktop.getDesktop().browse(outputFile.toURI());
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    // ========================================================================
+
+    private final String HTML_BINDINGS = "META-INF/bindings-html.xml";
+
+    private final Integer HTML_IMAGE_HEIGHT = Integer.valueOf(80);
+
+}
\ No newline at end of file
diff --git a/moxy/dynamic/flickr/src/main/java/eclipselink/example/moxy/dynamic/flickr/Main.java b/moxy/dynamic/flickr/src/main/java/eclipselink/example/moxy/dynamic/flickr/Main.java
index 0699b77..c5400c4 100644
--- a/moxy/dynamic/flickr/src/main/java/eclipselink/example/moxy/dynamic/flickr/Main.java
+++ b/moxy/dynamic/flickr/src/main/java/eclipselink/example/moxy/dynamic/flickr/Main.java
@@ -10,345 +10,25 @@
  ******************************************************************************/
 package eclipselink.example.moxy.dynamic.flickr;
 
-import java.awt.Desktop;
-import java.io.File;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
-import java.util.Random;
-import java.util.StringTokenizer;
-
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.Marshaller;
-import javax.xml.bind.Unmarshaller;
-import javax.xml.transform.stream.StreamSource;
 
 import org.eclipse.persistence.dynamic.DynamicEntity;
-import org.eclipse.persistence.jaxb.JAXBContextProperties;
-import org.eclipse.persistence.jaxb.MarshallerProperties;
-import org.eclipse.persistence.jaxb.UnmarshallerProperties;
-import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
-import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContextFactory;
-import org.eclipse.persistence.oxm.MediaType;
-
-import com.likethecolor.alchemy.api.Client;
-import com.likethecolor.alchemy.api.call.RankedConceptsCall;
-import com.likethecolor.alchemy.api.call.type.CallTypeText;
-import com.likethecolor.alchemy.api.entity.ConceptAlchemyEntity;
-import com.likethecolor.alchemy.api.entity.Response;
-import com.likethecolor.alchemy.api.params.ConceptParams;
 
 public class Main {
 
-    // The JAXBContext that we will use to read Reddit / Flickr data, and write HTML
-    private DynamicJAXBContext context;
-
-    // RedditPost:url -> RedditPost
-    HashMap<Object, DynamicEntity> redditMap;
-    // RedditPost:url -> FlickrResults
-    HashMap<Object, DynamicEntity> flickrMap;
-
-    File outputFile;
-
-    // ========================================================================
-
     public static void main(String[] args) {
-        new Main().run();
-    }
-
-    private void run() {
+        String topic = "software";
+        
         try {
-            init();
+            Map<Object, DynamicEntity> redditResults = new RedditReader().readRedditPosts(topic);
+            Map<Object, DynamicEntity> flickrResults = new FlikrReader().readFlickrResults(redditResults);
 
-            readRedditPosts();
-            findFlickrResults();
-            writeHtml();
-            launchSystemBrowser();
+            HTMLWriter writer = new HTMLWriter();
+            writer.write(topic, 6, redditResults, flickrResults);
+            writer.launchSystemBrowser();
         } catch (Exception e) {
             e.printStackTrace();
         }
     }
 
-    private void init() throws Exception {
-        ClassLoader loader = Thread.currentThread().getContextClassLoader();
-
-        InputStream redditBindings = loader.getResourceAsStream(REDDIT_BINDINGS);
-        InputStream flickrBindings = loader.getResourceAsStream(FLICKR_BINDINGS);
-        InputStream htmlBindings = loader.getResourceAsStream(HTML_BINDINGS);
-
-        ArrayList<InputStream> dataBindings = new ArrayList<InputStream>(3);
-        dataBindings.add(redditBindings);
-        dataBindings.add(flickrBindings);
-        dataBindings.add(htmlBindings);
-
-        Map<String, Object> properties = new HashMap<String, Object>();
-        properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, dataBindings);
-        context = DynamicJAXBContextFactory.createContextFromOXM(loader, properties);
-
-        redditMap = new HashMap<Object, DynamicEntity>();
-        flickrMap = new HashMap<Object, DynamicEntity>();
-
-        outputFile = new File("output.html");
-    }
-
-    private void readRedditPosts() throws Exception {
-        Unmarshaller u = context.createUnmarshaller();
-        u.setProperty(UnmarshallerProperties.MEDIA_TYPE, MediaType.APPLICATION_JSON);
-        u.setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT, false);
-
-        Class<? extends DynamicEntity> redditResultsClass = context.newDynamicEntity("eclipselink.example.moxy.dynamic.flickr.RedditResults").getClass();
-
-        System.out.println();
-        System.out.print("Reading Today's Hot Topics from Reddit r/" + SUBREDDIT + "... ");
-        DynamicEntity redditResults = u.unmarshal(new StreamSource(REDDIT_URL), redditResultsClass).getValue();
-        System.out.println("Done.");
-
-        ArrayList<DynamicEntity> posts = redditResults.get("posts");
-        for (DynamicEntity post : posts) {
-            redditMap.put(post.get("url"), post);
-        }
-    }
-
-    private void findFlickrResults() throws Exception {
-        for (Object postUrl : redditMap.keySet()) {
-            DynamicEntity post = redditMap.get(postUrl);
-
-            System.out.println();
-            System.out.println("Headline: [" + post.get("title") + "]");
-
-            String keywords = extractConcepts(post.get("title").toString());
-
-            String flickrUrlString = FLICKR_URL + keywords;
-            System.out.print("Searching Flickr: [" + flickrUrlString + "]... ");
-            InputStream flickrStream = new URL(flickrUrlString).openConnection().getInputStream();
-            System.out.println("Done.");
-
-            Unmarshaller u = context.createUnmarshaller();
-            DynamicEntity flickrResults = (DynamicEntity) u.unmarshal(flickrStream);
-
-            flickrMap.put(postUrl, flickrResults);
-
-            ArrayList<DynamicEntity> flickerItems = flickrResults.get("items");
-            if (flickerItems != null) {
-                int size = flickerItems.size();
-                if (size >= IMAGE_LIMIT) {
-                    size = IMAGE_LIMIT;
-                }
-                for (int i = 0; i < size; i++) {
-                    System.out.println("\t" + flickerItems.get(i).get("imageUrl"));
-                }
-            } else {
-                System.out.println("\tNo results found.");
-            }
-        }
-    }
-
-    private void writeHtml() throws Exception {
-        DynamicEntity html = context.newDynamicEntity("eclipselink.example.moxy.dynamic.flickr.HtmlPage");
-        html.set("title", "EclipseLink MOXy - Dynamic JAXB");
-        html.set("css", "style.css");
-        html.set("rel", "stylesheet");
-        html.set("type", "text/css");
-        html.set("media", "screen");
-
-        DynamicEntity body = context.newDynamicEntity("eclipselink.example.moxy.dynamic.flickr.HtmlBody");
-        body.set("title", "Reddit /" + SUBREDDIT + " - Today's Top Posts");
-
-        ArrayList<DynamicEntity> divs = new ArrayList<DynamicEntity>();
-
-        for (Object postUrl : redditMap.keySet()) {
-            DynamicEntity post = redditMap.get(postUrl);
-            DynamicEntity flickrResults = flickrMap.get(postUrl);
-
-            // Article Link
-            // ================================================================
-
-            DynamicEntity redditDiv = context.newDynamicEntity("eclipselink.example.moxy.dynamic.flickr.HtmlDiv");
-            redditDiv.set("id", "redditPost");
-
-            ArrayList<DynamicEntity> divContent = new ArrayList<DynamicEntity>();
-
-            DynamicEntity redditLink = context.newDynamicEntity("eclipselink.example.moxy.dynamic.flickr.HtmlTextLink");
-            redditLink.set("url", post.get("url"));
-            redditLink.set("title", post.get("title"));
-            divContent.add(redditLink);
-
-            redditDiv.set("span", divContent);
-
-            // Flickr description and images
-            // ================================================================
-
-            DynamicEntity flickrDiv = context.newDynamicEntity("eclipselink.example.moxy.dynamic.flickr.HtmlDiv");
-            flickrDiv.set("id", "flickrResults");
-
-            divContent = new ArrayList<DynamicEntity>();
-
-            DynamicEntity flickrDescription = context.newDynamicEntity("eclipselink.example.moxy.dynamic.flickr.HtmlText");
-            flickrDescription.set("text", flickrResults.get("description"));
-            divContent.add(flickrDescription);
-
-            ArrayList<DynamicEntity> flickrItems = flickrResults.get("items");
-
-            int counter = 0;
-            if (flickrItems != null) {
-                Collections.shuffle(flickrItems, new Random(System.nanoTime()));
-                for (DynamicEntity flickrItem : flickrItems) {
-                    DynamicEntity flickrImageLink = context.newDynamicEntity("eclipselink.example.moxy.dynamic.flickr.HtmlImageLink");
-                    flickrImageLink.set("url", flickrItem.get("flickrPage"));
-                    flickrImageLink.set("image", flickrItem.get("imageUrl"));
-                    flickrImageLink.set("height", HTML_IMAGE_HEIGHT);
-                    divContent.add(flickrImageLink);
-                    counter++;
-                    if (counter == IMAGE_LIMIT) {
-                        break;
-                    }
-                }
-            } else {
-                DynamicEntity noneText = context.newDynamicEntity("eclipselink.example.moxy.dynamic.flickr.HtmlText");
-                noneText.set("text", "No results found.");
-                divContent.add(noneText);
-            }
-            flickrDiv.set("span", divContent);
-
-            divs.add(redditDiv);
-            divs.add(flickrDiv);
-        }
-
-        body.set("divs", divs);
-
-        html.set("body", body);
-
-        Marshaller m = context.createMarshaller();
-        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
-        m.setProperty(Marshaller.JAXB_FRAGMENT, true);
-        m.marshal(html, outputFile);
-    }
-
-    // ========================================================================
-
-    /**
-     * This method uses the AlchemyAPI web service to determine the "concepts"
-     * contained in the headline.  It does not use EclipseLink and is used solely for
-     * the purpose of this example application.
-     *
-     * @see <a href="http://www.alchemyapi.com">AlchemyAPI</a>
-     */
-    @SuppressWarnings("unchecked")
-    private String extractConcepts(String postTitle) {
-        try {
-            Client client = new Client(ALCHEMY_KEY);
-
-            ConceptParams params = new ConceptParams();
-            params.setMaxRetrieve(ALCHEMY_CONCEPTS_TO_RETURN);
-
-            CallTypeText callType = new CallTypeText(postTitle);
-            RankedConceptsCall call = new RankedConceptsCall(callType, params);
-            Response<ConceptAlchemyEntity> response = client.call(call);
-
-            String concepts = "";
-
-            Iterator<ConceptAlchemyEntity> it = response.iterator();
-            if (!it.hasNext()) {
-                // If Alchemy didn't find any concepts, use string length algorithm
-                return extractKeywords(postTitle);
-            } else {
-                while (it.hasNext()) {
-                    ConceptAlchemyEntity alchemyEntity = it.next();
-                    concepts +=  alchemyEntity.getConcept();
-                    if (it.hasNext()) {
-                        concepts += ",";
-                    }
-                }
-            }
-
-            concepts = concepts.replace(" ", "+");
-
-            return concepts;
-        } catch (Exception e) {
-            return extractKeywords(postTitle);
-        }
-    }
-
-    private String extractKeywords(String postTitle) {
-        StringTokenizer tokenizer = new StringTokenizer(postTitle, ",.!?()[]'\"- \t\n\r\f");
-
-        ArrayList<String> words = new ArrayList<String>();
-
-        while (tokenizer.hasMoreElements()) {
-            words.add(tokenizer.nextToken());
-        }
-
-        // Sort words, longest one first
-        Collections.sort(words, new StringLengthComparator());
-
-        String keywords = null;
-        if (words.size() > 1) {
-            keywords = words.get(0) + "," + words.get(1);
-        } else {
-            keywords = words.get(0);
-        }
-
-        return keywords;
-    }
-
-    private void launchSystemBrowser() {
-        try {
-            Desktop.getDesktop().browse(outputFile.toURI());
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    private void writeJsonBindings() throws Exception {
-        ClassLoader loader = Thread.currentThread().getContextClassLoader();
-        InputStream bindingsXml = loader.getResourceAsStream("META-INF/bindings-flickr.xml");
-        JAXBContext ctx = JAXBContext.newInstance("org.eclipse.persistence.jaxb.xmlmodel");
-        Object bindings = ctx.createUnmarshaller().unmarshal(bindingsXml);
-
-        Marshaller m = ctx.createMarshaller();
-        m.setProperty(MarshallerProperties.MEDIA_TYPE, MediaType.APPLICATION_JSON);
-        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
-        m.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, false);
-        m.marshal(bindings, System.out);
-    }
-
-    // ========================================================================
-
-    public class StringLengthComparator implements Comparator<String> {
-        public int compare(String o1, String o2) {
-            if (o1.length() > o2.length()) {
-                return -1;
-            } else if (o1.length() < o2.length()) {
-                return 1;
-            } else {
-                return 0;
-            }
-        }
-    }
-
-    // ========================================================================
-
-    // See http://www.reddit.com/dev/api
-    private final int REDDIT_LIMIT = 5;
-    private final String SUBREDDIT = "technology";
-    private final String REDDIT_URL = "http://www.reddit.com/r/" + SUBREDDIT + "/top/.json?sort=top&t=today&limit=" + REDDIT_LIMIT;
-
-    // See http://www.flickr.com/services/feeds/
-    private final int IMAGE_LIMIT = 6;
-    private final String FLICKR_URL = "http://api.flickr.com/services/feeds/photos_public.gne?safe_search=1&tags=";
-
-    private final String REDDIT_BINDINGS = "META-INF/bindings-reddit.xml";
-    private final String FLICKR_BINDINGS = "META-INF/bindings-flickr.json";
-    private final String HTML_BINDINGS = "META-INF/bindings-html.xml";
-
-    private final int ALCHEMY_CONCEPTS_TO_RETURN = 2;
-    private final String ALCHEMY_KEY = "/META-INF/a.key";
-
-    private final Integer HTML_IMAGE_HEIGHT = Integer.valueOf(80);
-
 }
\ No newline at end of file
diff --git a/moxy/dynamic/flickr/src/main/java/eclipselink/example/moxy/dynamic/flickr/RedditReader.java b/moxy/dynamic/flickr/src/main/java/eclipselink/example/moxy/dynamic/flickr/RedditReader.java
new file mode 100644
index 0000000..1f793a8
--- /dev/null
+++ b/moxy/dynamic/flickr/src/main/java/eclipselink/example/moxy/dynamic/flickr/RedditReader.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ *
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ ******************************************************************************/
+package eclipselink.example.moxy.dynamic.flickr;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.stream.StreamSource;
+
+import org.eclipse.persistence.dynamic.DynamicEntity;
+import org.eclipse.persistence.jaxb.JAXBContextProperties;
+import org.eclipse.persistence.jaxb.UnmarshallerProperties;
+import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
+import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContextFactory;
+import org.eclipse.persistence.oxm.MediaType;
+
+public class RedditReader {
+
+    private DynamicJAXBContext context;
+
+    public RedditReader() {
+        ClassLoader loader = Thread.currentThread().getContextClassLoader();
+
+        InputStream redditBindings = loader.getResourceAsStream(REDDIT_BINDINGS);
+
+        ArrayList<InputStream> dataBindings = new ArrayList<InputStream>(3);
+        dataBindings.add(redditBindings);
+
+        Map<String, Object> properties = new HashMap<String, Object>();
+        properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, dataBindings);
+        try {
+            context = DynamicJAXBContextFactory.createContextFromOXM(loader, properties);
+        } catch (JAXBException e) {
+            throw new RuntimeException("Context creation failed", e);
+        }
+    }
+
+    public Map<Object, DynamicEntity> readRedditPosts(String topic) throws Exception {
+        Unmarshaller u = context.createUnmarshaller();
+        u.setProperty(UnmarshallerProperties.MEDIA_TYPE, MediaType.APPLICATION_JSON);
+        u.setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT, false);
+
+        Class<? extends DynamicEntity> redditResultsClass = context.newDynamicEntity("eclipselink.example.moxy.dynamic.flickr.RedditResults").getClass();
+
+        System.out.println();
+        System.out.print("Reading Today's Hot Topics from Reddit r/" + topic + "... ");
+        DynamicEntity redditResults = u.unmarshal(new StreamSource(getRedditURL(topic)), redditResultsClass).getValue();
+        System.out.println("Done.");
+
+        List<DynamicEntity> posts = redditResults.get("posts");
+        Map<Object, DynamicEntity> results = new HashMap<Object, DynamicEntity>();
+
+        for (DynamicEntity post : posts) {
+            results.put(post.get("url"), post);
+        }
+
+        return results;
+    }
+    
+    private String getRedditURL(String topic) {
+        return "http://www.reddit.com/r/" + topic + "/top/.json?sort=top&t=today&limit=" + REDDIT_LIMIT;
+    }
+
+    // See http://www.reddit.com/dev/api
+    private final int REDDIT_LIMIT = 5;
+
+    private final String REDDIT_BINDINGS = "META-INF/bindings-reddit.xml";
+}
\ No newline at end of file