diff --git a/org.eclipse.ice.dev/.gitignore b/org.eclipse.ice.dev/.gitignore
index 0f630157f4bf530f9697788f383cabaab83dc2e8..e4df9b2abca99d5c34e012b667282a0ccf423a0f 100644
--- a/org.eclipse.ice.dev/.gitignore
+++ b/org.eclipse.ice.dev/.gitignore
@@ -1,2 +1,3 @@
 /target/
 /bin/
+.factorypath
diff --git a/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations.proxytest/.classpath b/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations.proxytest/.classpath
index d66f66369ba7e695bb907957bafee643d23a5820..edcf841d21c05aff38d44630d216029bd76d72bc 100644
--- a/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations.proxytest/.classpath
+++ b/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations.proxytest/.classpath
@@ -24,5 +24,16 @@
 		</attributes>
 	</classpathentry>
 	<classpathentry kind="src" path="/org.eclipse.ice.dev.annotations"/>
+	<classpathentry kind="src" path="target/generated-sources/annotations">
+		<attributes>
+			<attribute name="optional" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
 	<classpathentry kind="output" path="target/classes"/>
 </classpath>
diff --git a/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/DataElementProcessor.java b/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/DataElementProcessor.java
index 7876883d1220db90d4ce05660bd7d58b7fe76132..17536a24f6cdb791441a24a86fce749673180b15 100644
--- a/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/DataElementProcessor.java
+++ b/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/DataElementProcessor.java
@@ -8,7 +8,6 @@ import java.io.Writer;
 import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Properties;
 import java.util.Set;
 
 import javax.annotation.processing.AbstractProcessor;
@@ -26,8 +25,6 @@ import javax.tools.Diagnostic;
 import javax.tools.JavaFileObject;
 import javax.tools.StandardLocation;
 
-import org.apache.velocity.VelocityContext;
-import org.apache.velocity.app.Velocity;
 import org.eclipse.ice.dev.annotations.DataElement;
 import org.eclipse.ice.dev.annotations.Persisted;
 
@@ -50,31 +47,6 @@ import com.google.auto.service.AutoService;
 @SupportedSourceVersion(SourceVersion.RELEASE_11)
 @AutoService(Processor.class)
 public class DataElementProcessor extends AbstractProcessor {
-
-	/**
-	 * Location of DataElement template for use with velocity.
-	 *
-	 * Use of Velocity ClasspathResourceLoader means files are discovered relative
-	 * to the src/main/resources folder.
-	 */
-	private static final String DATAELEMENT_TEMPLATE = "templates/DataElement.vm";
-
-	/**
-	 * Location of PersistenceHandler template for use with velocity.
-	 *
-	 * Use of Velocity ClasspathResourceLoader means files are discovered relative
-	 * to the src/main/resources folder.
-	 */
-	private static final String PERSISTENCE_HANDLER_TEMPLATE = "templates/PersistenceHandler.vm";
-
-	/**
-	 * Location of Interface template for use with velocity.
-	 *
-	 * Use of Velocity ClasspathResourceLoader means files are discovered relative
-	 * to the src/main/resources folder.
-	 */
-	private static final String INTERFACE_TEMPLATE = "templates/ElementInterface.vm";
-
 	/**
 	 * Return stack trace as string.
 	 * @param e subject exception
@@ -97,15 +69,6 @@ public class DataElementProcessor extends AbstractProcessor {
 		messager = env.getMessager();
 		elementUtils = env.getElementUtils();
 		mapper = new ObjectMapper();
-
-		// Set up Velocity using the Singleton approach; ClasspathResourceLoader allows
-		// us to load templates from src/main/resources
-		final Properties p = new Properties();
-		for (VelocityProperty vp : VelocityProperty.values()) {
-			p.setProperty(vp.key(), vp.value());
-		}
-		Velocity.init(p);
-
 		super.init(env);
 	}
 
@@ -127,7 +90,7 @@ public class DataElementProcessor extends AbstractProcessor {
 				writeInterface(dataElement, fields);
 
 				// Write the DataElement Implementation to file.
-				writeClass(dataElement, fields);
+				writeImpl(dataElement, fields);
 
 				// Check if Persistence should be generated.
 				if (dataElement.hasAnnotation(Persisted.class)) {
@@ -177,19 +140,17 @@ public class DataElementProcessor extends AbstractProcessor {
 	 * @param fields
 	 * @throws IOException
 	 */
-	private void writeClass(DataElementSpec element, final Fields fields) throws IOException {
-		// Prepare context of template
-		final VelocityContext context = new VelocityContext();
-		context.put(DataElementTemplateProperty.PACKAGE.getKey(), element.getPackageName());
-		context.put(DataElementTemplateProperty.INTERFACE.getKey(), element.getName());
-		context.put(DataElementTemplateProperty.CLASS.getKey(), element.getImplName());
-		context.put(DataElementTemplateProperty.FIELDS.getKey(), fields);
-
-		// Write to file
+	private void writeImpl(DataElementSpec element, final Fields fields) throws IOException {
 		final JavaFileObject generatedClassFile = processingEnv.getFiler()
 			.createSourceFile(element.getQualifiedImplName());
 		try (Writer writer = generatedClassFile.openWriter()) {
-			Velocity.mergeTemplate(DATAELEMENT_TEMPLATE, "UTF-8", context, writer);
+			ImplementationWriter.builder()
+				.packageName(element.getPackageName())
+				.className(element.getImplName())
+				.interfaceName(element.getName())
+				.fields(fields)
+				.build()
+				.write(writer);
 		}
 	}
 
@@ -205,38 +166,19 @@ public class DataElementProcessor extends AbstractProcessor {
 		final String collectionName,
 		Fields fields
 	) throws IOException {
-		// Prepare context of template
-		final VelocityContext context = new VelocityContext();
-		context.put(
-			PersistenceHandlerTemplateProperty.PACKAGE.getKey(),
-			element.getPackageName()
-		);
-		context.put(
-			PersistenceHandlerTemplateProperty.ELEMENT_INTERFACE.getKey(),
-			element.getName()
-		);
-		context.put(
-			PersistenceHandlerTemplateProperty.CLASS.getKey(),
-			element.getPersistenceHandlerName()
-		);
-		context.put(
-			PersistenceHandlerTemplateProperty.COLLECTION.getKey(),
-			collectionName
-		);
-		context.put(
-			PersistenceHandlerTemplateProperty.IMPLEMENTATION.getKey(),
-			element.getImplName()
-		);
-		context.put(
-			PersistenceHandlerTemplateProperty.FIELDS.getKey(),
-			fields
-		);
-
 		// Write to file
 		final JavaFileObject generatedClassFile = processingEnv.getFiler()
 			.createSourceFile(element.getQualifiedPersistenceHandlerName());
 		try (Writer writer = generatedClassFile.openWriter()) {
-			Velocity.mergeTemplate(PERSISTENCE_HANDLER_TEMPLATE, "UTF-8", context, writer);
+			PersistenceHandlerWriter.builder()
+				.packageName(element.getPackageName())
+				.elementInterface(element.getName())
+				.className(element.getPersistenceHandlerName())
+				.implementation(element.getImplName())
+				.collection(collectionName)
+				.fields(fields)
+				.build()
+				.write(writer);
 		}
 	}
 
@@ -250,26 +192,15 @@ public class DataElementProcessor extends AbstractProcessor {
 		DataElementSpec element,
 		Fields fields
 	) throws IOException {
-		// Prepare context of template
-		final VelocityContext context = new VelocityContext();
-		context.put(
-			InterfaceTemplateProperty.PACKAGE.getKey(),
-			element.getPackageName()
-		);
-		context.put(
-			InterfaceTemplateProperty.INTERFACE.getKey(),
-			element.getName()
-		);
-		context.put(
-			PersistenceHandlerTemplateProperty.FIELDS.getKey(),
-			fields
-		);
-
-		// Write to file
 		final JavaFileObject generatedClassFile = processingEnv.getFiler()
 			.createSourceFile(element.getFullyQualifiedName());
 		try (Writer writer = generatedClassFile.openWriter()) {
-			Velocity.mergeTemplate(INTERFACE_TEMPLATE, "UTF-8", context, writer);
+			InterfaceWriter.builder()
+				.packageName(element.getPackageName())
+				.interfaceName(element.getName())
+				.fields(fields)
+				.build()
+				.write(writer);
 		}
 	}
 }
diff --git a/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/DataElementTemplateProperty.java b/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/DataElementTemplateProperty.java
deleted file mode 100644
index 33c4e622f482f5ac9f046b2f2aa5e11074194235..0000000000000000000000000000000000000000
--- a/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/DataElementTemplateProperty.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.eclipse.ice.dev.annotations.processors;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * Enumeration for Keys used in DataElement Velocity Template.
- */
-@AllArgsConstructor
-enum DataElementTemplateProperty {
-	PACKAGE("package"),
-	FIELDS("fields"),
-	INTERFACE("interface"),
-	CLASS("class");
-
-	@Getter private String key;
-}
\ No newline at end of file
diff --git a/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/ImplementationWriter.java b/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/ImplementationWriter.java
new file mode 100644
index 0000000000000000000000000000000000000000..92accc8c84b1f1dcd180d7700d629de519eb351e
--- /dev/null
+++ b/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/ImplementationWriter.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2020- UT-Battelle, LLC.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Daniel Bluhm - Initial implementation
+ *******************************************************************************/
+
+package org.eclipse.ice.dev.annotations.processors;
+
+import lombok.Builder;
+
+/**
+ * Writer for DataElement Implementation classes.
+ * @author Daniel Bluhm
+ */
+public class ImplementationWriter extends VelocitySourceWriter {
+
+	/**
+	 * Location of DataElement template for use with velocity.
+	 *
+	 * Use of Velocity ClasspathResourceLoader means files are discovered relative
+	 * to the src/main/resources folder.
+	 */
+	private static final String IMPL_TEMPLATE = "templates/DataElement.vm";
+
+	/**
+	 * Context key for package.
+	 */
+	private static final String PACKAGE = "package";
+
+	/**
+	 * Context key for interface.
+	 */
+	private static final String INTERFACE = "interface";
+
+	/**
+	 * Context key for fields.
+	 */
+	private static final String FIELDS = "fields";
+
+	/**
+	 * Context key for class.
+	 */
+	private static final String CLASS = "class";
+
+	@Builder
+	public ImplementationWriter(
+		String packageName, String interfaceName, String className, Fields fields
+	) {
+		super();
+		this.template = IMPL_TEMPLATE;
+		this.context.put(PACKAGE, packageName);
+		this.context.put(INTERFACE, interfaceName);
+		this.context.put(CLASS, className);
+		this.context.put(FIELDS, fields);
+	}
+}
diff --git a/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/InterfaceTemplateProperty.java b/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/InterfaceTemplateProperty.java
deleted file mode 100644
index b15ff2848a852b8e15789496818a085da63f34d8..0000000000000000000000000000000000000000
--- a/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/InterfaceTemplateProperty.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.eclipse.ice.dev.annotations.processors;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * Enumeration of keys of Interface Template.
- * @author Daniel Bluhm
- */
-@AllArgsConstructor
-enum InterfaceTemplateProperty {
-	PACKAGE("package"),
-	INTERFACE("interface"),
-	FIELDS("fields");
-
-	@Getter private String key;
-}
diff --git a/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/InterfaceWriter.java b/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/InterfaceWriter.java
new file mode 100644
index 0000000000000000000000000000000000000000..c0b68bb7cf5c944aa4f02d589f1e8f9f9e50840a
--- /dev/null
+++ b/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/InterfaceWriter.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2020- UT-Battelle, LLC.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Daniel Bluhm - Initial implementation
+ *******************************************************************************/
+
+package org.eclipse.ice.dev.annotations.processors;
+
+import lombok.Builder;
+import lombok.NonNull;
+
+/**
+ * Writer for DataElement Interfaces.
+ * @author Daniel Bluhm
+ */
+public class InterfaceWriter extends VelocitySourceWriter {
+
+	/**
+	 * Location of Interface template for use with velocity.
+	 *
+	 * Use of Velocity ClasspathResourceLoader means files are discovered relative
+	 * to the src/main/resources folder.
+	 */
+	private static final String TEMPLATE = "templates/ElementInterface.vm";
+
+	/**
+	 * Context key for package.
+	 */
+	private static final String PACKAGE = "package";
+
+	/**
+	 * Context key for interface.
+	 */
+	private static final String INTERFACE = "interface";
+
+	/**
+	 * Context key for fields.
+	 */
+	private static final String FIELDS = "fields";
+
+	@Builder
+	public InterfaceWriter(
+		String packageName, String interfaceName, @NonNull Fields fields
+	) {
+		super();
+		this.template = TEMPLATE;
+		context.put(PACKAGE, packageName);
+		context.put(INTERFACE, interfaceName);
+		context.put(FIELDS, fields);
+	}
+}
diff --git a/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/PersistenceHandlerTemplateProperty.java b/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/PersistenceHandlerTemplateProperty.java
deleted file mode 100644
index 53e51835f9533ed42a84e7e85de52aca0131536a..0000000000000000000000000000000000000000
--- a/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/PersistenceHandlerTemplateProperty.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.eclipse.ice.dev.annotations.processors;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * Enumeration of keys of Persistence Handler Template.
- * @author Daniel Bluhm
- */
-@AllArgsConstructor
-enum PersistenceHandlerTemplateProperty {
-	PACKAGE("package"),
-	ELEMENT_INTERFACE("elementInterface"),
-	CLASS("class"),
-	COLLECTION("collection"),
-	IMPLEMENTATION("implementation"),
-	FIELDS("fields");
-	
-	@Getter private String key;
-}
\ No newline at end of file
diff --git a/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/PersistenceHandlerWriter.java b/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/PersistenceHandlerWriter.java
new file mode 100644
index 0000000000000000000000000000000000000000..1ba3f8a996bb1a8bd37c926c5e2e80e0bc241375
--- /dev/null
+++ b/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/PersistenceHandlerWriter.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2020- UT-Battelle, LLC.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Daniel Bluhm - Initial implementation
+ *******************************************************************************/
+
+package org.eclipse.ice.dev.annotations.processors;
+
+import lombok.Builder;
+import lombok.NonNull;
+
+/**
+ * Writer for DataElement Persistence classes.
+ * @author Daniel Bluhm
+ */
+public class PersistenceHandlerWriter extends VelocitySourceWriter {
+
+	/**
+	 * Location of PersistenceHandler template for use with velocity.
+	 *
+	 * Use of Velocity ClasspathResourceLoader means files are discovered relative
+	 * to the src/main/resources folder.
+	 */
+	private static final String PERSISTENCE_HANDLER_TEMPLATE = "templates/PersistenceHandler.vm";
+
+	/**
+	 * Context key for package.
+	 */
+	private static final String PACKAGE = "package";
+
+	/**
+	 * Context key for element interface.
+	 */
+	private static final String ELEMENT_INTERFACE = "elementInterface";
+
+	/**
+	 * Context key for class
+	 */
+	private static final String CLASS = "class";
+
+	/**
+	 * Context key for collection.
+	 */
+	private static final String COLLECTION = "collection";
+
+	/**
+	 * Context key for implementation.
+	 */
+	private static final String IMPLEMENTATION = "implementation";
+
+	/**
+	 * Context key for fields.
+	 */
+	private static final String FIELDS = "fields";
+
+	@Builder
+	public PersistenceHandlerWriter(
+		String packageName, String elementInterface, String className,
+		String implementation, String collection, @NonNull Fields fields
+	) {
+		super();
+		this.template = PERSISTENCE_HANDLER_TEMPLATE;
+		this.context.put(PACKAGE, packageName);
+		this.context.put(ELEMENT_INTERFACE, elementInterface);
+		this.context.put(CLASS, className);
+		this.context.put(COLLECTION, collection);
+		this.context.put(IMPLEMENTATION, implementation);
+		this.context.put(FIELDS, fields);
+	}
+}
diff --git a/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/VelocityProperties.java b/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/VelocityProperties.java
new file mode 100644
index 0000000000000000000000000000000000000000..6ca86eee41445863be38bdf86fdeea97a5f704ea
--- /dev/null
+++ b/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/VelocityProperties.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2020- UT-Battelle, LLC.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Daniel Bluhm - Initial implementation
+ *******************************************************************************/
+
+package org.eclipse.ice.dev.annotations.processors;
+
+import java.util.Properties;
+
+/**
+ * Properties used to initialize Velocity.
+ */
+enum VelocityProperties {
+
+	// Set up Velocity using the Singleton approach; ClasspathResourceLoader allows
+	// us to load templates from src/main/resources
+	RESOURCE_LOADER("resource.loader", "class"),
+	CLASS_RESOURCE_LOADER(
+		"class.resource.loader.class",
+		"org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"
+	);
+
+	/**
+	 * Property key.
+	 */
+	private String key;
+
+	/**
+	 * Property value.
+	 */
+	private String value;
+
+	VelocityProperties(String key, String value) {
+		this.key = key;
+		this.value = value;
+	}
+
+	/**
+	 * Get key from enum.
+	 * @return key
+	 */
+	String key() {
+		return this.key;
+	}
+
+	/**
+	 * Get value from enum.
+	 * @return value
+	 */
+	String value() {
+		return this.value;
+	}
+
+	/**
+	 * Generate and return Properties from enum.
+	 * @return Properties
+	 */
+	public static Properties get() {
+		Properties p = new Properties();
+		for (VelocityProperties vp : VelocityProperties.values()) {
+			p.setProperty(vp.key(), vp.value());
+		}
+		return p;
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/VelocityProperty.java b/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/VelocityProperty.java
deleted file mode 100644
index 80b7eaac68a3b4c227872b27b82c49dbc5deb993..0000000000000000000000000000000000000000
--- a/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/VelocityProperty.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.eclipse.ice.dev.annotations.processors;
-
-/**
- * Properties used to initialize Velocity.
- */
-enum VelocityProperty {
-	RESOURCE_LOADER("resource.loader", "class"),
-	CLASS_RESOURCE_LOADER(
-		"class.resource.loader.class",
-		"org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"
-	);
-
-	private String key;
-	private String value;
-
-	VelocityProperty(String key, String value) {
-		this.key = key;
-		this.value = value;
-	}
-
-	String key() {
-		return this.key;
-	}
-
-	String value() {
-		return this.value;
-	}
-}
\ No newline at end of file
diff --git a/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/VelocitySourceWriter.java b/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/VelocitySourceWriter.java
new file mode 100644
index 0000000000000000000000000000000000000000..a49aa7187cfb79101bc5008210bb5b29cbe1c1bf
--- /dev/null
+++ b/org.eclipse.ice.dev/org.eclipse.ice.dev.annotations/src/main/java/org/eclipse/ice/dev/annotations/processors/VelocitySourceWriter.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2020- UT-Battelle, LLC.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Daniel Bluhm - Initial implementation
+ *******************************************************************************/
+
+package org.eclipse.ice.dev.annotations.processors;
+
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+
+/**
+ * Abstract base class for classes that render a Java Source file through
+ * velocity templates.
+ * @author Daniel Bluhm
+ */
+public abstract class VelocitySourceWriter {
+
+	protected String template;
+	protected Map<String, Object> context;
+	
+	public VelocitySourceWriter() {
+		this.context = new HashMap<>();
+	}
+
+	/**
+	 * Write the Java Source file to the open writer.
+	 * @param writer to which the java source will be written
+	 */
+	public void write(Writer writer) {
+		// Make sure Velocity is initialized. Subsequent calls are harmless.
+		Velocity.init(VelocityProperties.get());
+
+		// Make velocity context from generic map context.
+		Context velocityContext = new VelocityContext(context);
+
+		// Write template from context.
+		Velocity.mergeTemplate(template, "UTF-8", velocityContext, writer);
+	}
+}
diff --git a/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/.classpath b/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/.classpath
new file mode 100644
index 0000000000000000000000000000000000000000..eacc5f13553b202ae71979fadf87d957afd02692
--- /dev/null
+++ b/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/.classpath
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="test" value="true"/>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" path="target/generated-sources/annotations">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="ignore_optional_problems" value="true"/>
+			<attribute name="m2e-apt" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="ignore_optional_problems" value="true"/>
+			<attribute name="m2e-apt" value="true"/>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/.gitignore b/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..0f630157f4bf530f9697788f383cabaab83dc2e8
--- /dev/null
+++ b/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/.gitignore
@@ -0,0 +1,2 @@
+/target/
+/bin/
diff --git a/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/.project b/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/.project
new file mode 100644
index 0000000000000000000000000000000000000000..847fff5e73500fb1dc96246a3cb6d6b3f829349d
--- /dev/null
+++ b/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.ice.dev.pojofromjson</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/pom.xml b/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ea38932167bfa2fc33e59ea3382850aa49720e21
--- /dev/null
+++ b/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/pom.xml
@@ -0,0 +1,111 @@
+<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>
+	<groupId>org.eclipse.ice</groupId>
+	<artifactId>org.eclipse.ice.dev.pojofromjson</artifactId>
+	<packaging>jar</packaging>
+	<version>1.0-SNAPSHOT</version>
+	<name>org.eclipse.ice.dev.fromjson</name>
+	<url>http://maven.apache.org</url>
+	<properties>
+		<exec.mainClass>org.eclipse.ice.dev.pojofromjson.PojoFromJson</exec.mainClass>
+	</properties>
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-assembly-plugin</artifactId>
+				<executions>
+					<execution>
+						<phase>package</phase>
+						<goals>
+							<goal>single</goal>
+						</goals>
+						<configuration>
+							<archive>
+								<manifest>
+									<mainClass>
+										org.eclipse.ice.dev.pojofromjson.PojoFromJson
+									</mainClass>
+								</manifest>
+							</archive>
+							<descriptorRefs>
+								<descriptorRef>jar-with-dependencies</descriptorRef>
+							</descriptorRefs>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>3.8.1</version>
+				<configuration>
+					<release>11</release>
+					<annotationProcessorPaths>
+						<path>
+							<groupId>org.projectlombok</groupId>
+							<artifactId>lombok</artifactId>
+							<version>1.18.12</version>
+						</path>
+					</annotationProcessorPaths>
+				</configuration>
+			</plugin>
+			<plugin>
+				<artifactId>maven-surefire-plugin</artifactId>
+				<version>2.22.2</version>
+			</plugin>
+			<plugin>
+				<artifactId>maven-failsafe-plugin</artifactId>
+				<version>2.22.2</version>
+			</plugin>
+		</plugins>
+	</build>
+	<dependencies>
+		<dependency>
+			<groupId>org.junit.jupiter</groupId>
+			<artifactId>junit-jupiter-api</artifactId>
+			<version>5.6.2</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.junit.jupiter</groupId>
+			<artifactId>junit-jupiter-engine</artifactId>
+			<version>5.6.2</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.projectlombok</groupId>
+			<artifactId>lombok</artifactId>
+			<version>1.18.12</version>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>com.fasterxml.jackson.core</groupId>
+			<artifactId>jackson-core</artifactId>
+			<version>2.10.2</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>com.fasterxml.jackson.core</groupId>
+			<artifactId>jackson-databind</artifactId>
+			<version>2.10.2</version>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.eclipse.ice.dev</groupId>
+			<artifactId>org.eclipse.ice.dev.annotations</artifactId>
+			<version>3.0.0-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>com.google.jimfs</groupId>
+			<artifactId>jimfs</artifactId>
+			<version>1.1</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>com.beust</groupId>
+			<artifactId>jcommander</artifactId>
+			<version>1.78</version>
+		</dependency>
+	</dependencies>
+</project>
diff --git a/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/src/main/java/org/eclipse/ice/dev/pojofromjson/PojoFromJson.java b/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/src/main/java/org/eclipse/ice/dev/pojofromjson/PojoFromJson.java
new file mode 100644
index 0000000000000000000000000000000000000000..14e2a0815211eaf21ddcb294cce6710ba202191c
--- /dev/null
+++ b/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/src/main/java/org/eclipse/ice/dev/pojofromjson/PojoFromJson.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (c) 2020- UT-Battelle, LLC.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Daniel Bluhm - Initial implementation
+ *******************************************************************************/
+
+package org.eclipse.ice.dev.pojofromjson;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Writer;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.ice.dev.annotations.processors.DefaultFields;
+import org.eclipse.ice.dev.annotations.processors.Fields;
+import org.eclipse.ice.dev.annotations.processors.ImplementationWriter;
+import org.eclipse.ice.dev.annotations.processors.InterfaceWriter;
+
+import com.beust.jcommander.JCommander;
+import com.beust.jcommander.Parameter;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * Read JSON from Standard In and generate DataElement interface and
+ * implementation.
+ * @author Daniel Bluhm
+ */
+public class PojoFromJson {
+
+	/**
+	 * Mapper used for deserializing POJO Outline JSON
+	 */
+	private static ObjectMapper mapper = new ObjectMapper();
+
+	/**
+	 * List of files to operate on.
+	 */
+	@Parameter(description = "FILE [FILE...]")
+	private List<String> jsonFiles = new ArrayList<>();
+
+	/**
+	 * Directory to output generated files into.
+	 */
+	@Parameter(names = {"-o", "--output"}, description = "Output directory")
+	private String output = ".";
+
+	/**
+	 * Display help text.
+	 */
+	@Parameter(names = "--help", description = "Display this usage text", help = true)
+	private boolean help;
+
+	/**
+	 * Read from Input and write interface and implementation to files in
+	 * destination.
+	 * @param is InputStream of POJO Outline JSON
+	 * @param destination directory in which files will be generated
+	 * @throws JsonParseException On failure to parse POJO Outline JSON
+	 * @throws JsonMappingException On failure to map to POJO Outline
+	 * @throws IOException On failure to open file for writing
+	 */
+	public static void handleInputJson(
+		InputStream is, Path destination
+	) throws JsonParseException, JsonMappingException, IOException {
+		// Parse outline from input stream
+		PojoOutline pojo = mapper.readValue(is, PojoOutline.class);
+
+		// Collect fields
+		Fields fields = new Fields();
+		fields.collect(DefaultFields.get());
+		fields.collect(pojo.getFields());
+
+		// Write Interface
+		try (Writer elementInterface = Files.newBufferedWriter(
+			destination.resolve(pojo.getElement() + ".java")
+		)) {
+			InterfaceWriter.builder()
+				.packageName(pojo.getPackageName())
+				.interfaceName(pojo.getElement())
+				.fields(fields)
+				.build()
+				.write(elementInterface);
+		}
+
+		// Write implementation
+		try (Writer elementImpl = Files.newBufferedWriter(
+			destination.resolve(pojo.getImplementation() + ".java")
+		)) {
+			ImplementationWriter.builder()
+				.packageName(pojo.getPackageName())
+				.interfaceName(pojo.getElement())
+				.className(pojo.getImplementation())
+				.fields(fields)
+				.build()
+				.write(elementImpl);
+		}
+	}
+
+	/**
+	 * Execution entry point
+	 * @param args from command line
+	 */
+	public static void main(String[] args) {
+		PojoFromJson pfj = new PojoFromJson();
+		pfj.run(args);
+	}
+
+	/**
+	 * Read JSON form Standard In or from arguments and generate DataElement
+	 * interfaces and implementations.
+	 * @param args from command line
+	 */
+	public void run(String... args) {
+		JCommander jcomm = JCommander.newBuilder()
+			.addObject(this)
+			.build();
+		jcomm.setProgramName("POJOfromJSON");
+		jcomm.parse(args);
+
+		if (help) {
+			jcomm.usage();
+			return;
+		}
+
+		try {
+			if (jsonFiles.size() == 0) {
+				handleInputJson(System.in, Path.of(output));
+			}
+			for (String filePath : jsonFiles) {
+				try (FileInputStream inputJson = new FileInputStream(filePath)) {
+					handleInputJson(inputJson, Path.of(output));
+				}
+			}
+		} catch (Exception ex) {
+			System.err.println(ex.getMessage());
+			System.exit(1);
+		}
+	}
+}
diff --git a/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/src/main/java/org/eclipse/ice/dev/pojofromjson/PojoOutline.java b/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/src/main/java/org/eclipse/ice/dev/pojofromjson/PojoOutline.java
new file mode 100644
index 0000000000000000000000000000000000000000..574f25c11a1ad0534997aefbc95a9f788334d4f9
--- /dev/null
+++ b/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/src/main/java/org/eclipse/ice/dev/pojofromjson/PojoOutline.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2020- UT-Battelle, LLC.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Daniel Bluhm - Initial implementation
+ *******************************************************************************/
+
+package org.eclipse.ice.dev.pojofromjson;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.ice.dev.annotations.processors.Field;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
+
+import lombok.Builder;
+import lombok.Data;
+import lombok.NonNull;
+import lombok.Singular;
+
+/**
+ * Representation of information read in via JSON for POJO generation.
+ * @author Daniel Bluhm
+ */
+@Data
+@Builder
+@JsonDeserialize(builder = PojoOutline.PojoOutlineBuilder.class)
+public class PojoOutline {
+
+	/**
+	 * Default suffix for implementation names.
+	 */
+	private static final String IMPL_SUFFIX = "Implementation";
+
+	/**
+	 * Package of the generated classes.
+	 */
+	@JsonProperty("package")
+	@NonNull private String packageName;
+
+	/**
+	 * Name of the Element (interface) to be generated.
+	 */
+	@NonNull private String element;
+
+	/**
+	 * Name of the implementation to be generated. If null, element + IMPL_SUFFIX is
+	 * used.
+	 */
+	private String implementation;
+
+	/**
+	 * List of fields to generate on element.
+	 */
+	@Singular("field") private List<Field> fields;
+
+	/**
+	 * Get name of the implementation to generate.
+	 * @return implementation name.
+	 */
+	public String getImplementation() {
+		if (this.implementation == null) {
+			return this.element + IMPL_SUFFIX;
+		}
+		return this.implementation;
+	}
+	
+	/**
+	 * JSON Serialization info for Builder.
+	 */
+	private interface PojoOutlineBuilderMeta {
+		@JsonDeserialize(contentAs = Field.class)
+		public PojoOutlineBuilder fields(Collection<? extends Field> fields);
+
+		@JsonProperty("package")
+		public PojoOutlineBuilder packageName(@NonNull String package_);
+	}
+
+	/**
+	 * JSON Serialization info for Builder.
+	 */
+	@JsonPOJOBuilder(withPrefix = "")
+	public static class PojoOutlineBuilder implements PojoOutlineBuilderMeta {}
+}
diff --git a/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/src/test/java/org/eclipse/ice/tests/dev/pojofromjson/PojoFromJsonTest.java b/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/src/test/java/org/eclipse/ice/tests/dev/pojofromjson/PojoFromJsonTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..393363602fb8db85c3515c183d3006382edf447d
--- /dev/null
+++ b/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/src/test/java/org/eclipse/ice/tests/dev/pojofromjson/PojoFromJsonTest.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2020- UT-Battelle, LLC.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Daniel Bluhm - Initial implementation
+ *******************************************************************************/
+
+package org.eclipse.ice.tests.dev.pojofromjson;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.FileSystem;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.eclipse.ice.dev.pojofromjson.PojoFromJson;
+import org.junit.jupiter.api.Test;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.google.common.jimfs.Configuration;
+import com.google.common.jimfs.Jimfs;
+
+/**
+ * Test PojoFromJson.
+ */
+class PojoFromJsonTest {
+
+	/**
+	 * Source JSON.
+	 */
+	private static final String TEST_ELEMENT_JSON = "TestElement.json";
+
+	/**
+	 * Interface destination file name.
+	 */
+	private static final String TEST_ELEMENT_INTERFACE = "TestElement.java";
+
+	/**
+	 * Implementation destination file name.
+	 */
+	private static final String TEST_ELEMENT_IMPLEMENTATION = "TestElementImplementation.java";
+
+	/**
+	 * @return InputStream for JSON
+	 * @throws FileNotFoundException
+	 */
+	public InputStream getTestElementJsonStream() throws FileNotFoundException {
+		return new FileInputStream(
+			getClass().getClassLoader().getResource(TEST_ELEMENT_JSON).getPath()
+		);
+	}
+
+	/**
+	 * @return Path to in-memory destination.
+	 * @throws IOException
+	 */
+	public Path inMemoryDestination() throws IOException {
+		FileSystem fs = Jimfs.newFileSystem(Configuration.unix());
+		Path dest = fs.getPath("/dest");
+		Files.createDirectory(dest);
+		return dest;
+	}
+
+	/**
+	 * Test that handleInputJson generates an interface and implementation as
+	 * expected.
+	 *
+	 * There is no need to test the contents of the generated files as that is
+	 * tested in
+	 * {@link org.eclipse.ice.tests.dev.annotations.processors.DataElementProcessorTest}.
+	 * @throws JsonParseException
+	 * @throws JsonMappingException
+	 * @throws FileNotFoundException
+	 * @throws IOException
+	 */
+	@Test
+	public void testInterfaceAndImplementationGenerated()
+		throws JsonParseException, JsonMappingException, FileNotFoundException,
+		IOException
+	{
+		Path destination = inMemoryDestination();
+		PojoFromJson.handleInputJson(
+			getTestElementJsonStream(), destination
+		);
+		assertTrue(Files.exists(destination.resolve(TEST_ELEMENT_INTERFACE)));
+		assertTrue(Files.exists(destination.resolve(TEST_ELEMENT_IMPLEMENTATION)));
+	}
+}
diff --git a/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/src/test/java/org/eclipse/ice/tests/dev/pojofromjson/PojoOutlineTest.java b/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/src/test/java/org/eclipse/ice/tests/dev/pojofromjson/PojoOutlineTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..6433489d5a915345b1167a3a2ca93a60a48cbdde
--- /dev/null
+++ b/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/src/test/java/org/eclipse/ice/tests/dev/pojofromjson/PojoOutlineTest.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2020- UT-Battelle, LLC.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Daniel Bluhm - Initial implementation
+ *******************************************************************************/
+
+package org.eclipse.ice.tests.dev.pojofromjson;
+
+import org.eclipse.ice.dev.annotations.processors.Field;
+import org.eclipse.ice.dev.pojofromjson.PojoOutline;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.Test;
+
+public class PojoOutlineTest {
+
+	@Test
+	public void testSerialization() throws JsonProcessingException {
+		PojoOutline pojo = PojoOutline.builder()
+			.packageName("testpackage")
+			.element("TestElement")
+			.field(
+				Field.builder()
+					.name("test")
+					.type(String.class)
+					.docString("Test docs.")
+					.match(false)
+					.primitive(true)
+					.nullable(true)
+					.alias(Field.builder().name("another").getter(true).build())
+					.build()
+			).build();
+
+		ObjectMapper mapper = new ObjectMapper();
+		String pojoJson = mapper.writeValueAsString(pojo);
+		System.out.println(pojoJson);
+		PojoOutline rehydratedPojo = mapper.readValue(pojoJson, PojoOutline.class);
+		assertEquals(pojo, rehydratedPojo);
+	}
+
+	@Test
+	public void testImplementation() {
+		PojoOutline pojo = PojoOutline.builder()
+			.packageName("testpackage")
+			.element("TestElement")
+			.field(
+				Field.builder()
+					.name("test")
+					.type(String.class)
+					.docString("Test docs.")
+					.match(false)
+					.primitive(true)
+					.nullable(true)
+					.getter(false)
+					.setter(false)
+					.alias(Field.builder().name("another").getter(true).build())
+					.build()
+			).build();
+
+		assertEquals("TestElementImplementation", pojo.getImplementation());
+
+		pojo = PojoOutline.builder()
+			.packageName("testpackage")
+			.element("TestElement")
+			.implementation("TestElementImpl")
+			.field(
+				Field.builder()
+					.name("test")
+					.type(String.class)
+					.docString("Test docs.")
+					.match(false)
+					.primitive(true)
+					.nullable(true)
+					.getter(false)
+					.setter(false)
+					.alias(Field.builder().name("another").getter(true).build())
+					.build()
+			).build();
+		assertEquals("TestElementImpl", pojo.getImplementation());
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/src/test/resources/TestElement.json b/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/src/test/resources/TestElement.json
new file mode 100644
index 0000000000000000000000000000000000000000..764456f0a22d801dc69a9d53c0809cea42cf5008
--- /dev/null
+++ b/org.eclipse.ice.dev/org.eclipse.ice.dev.pojofromjson/src/test/resources/TestElement.json
@@ -0,0 +1,8 @@
+{
+	"package": "testpackage",
+	"element": "TestElement",
+	"fields": [{
+		"name": "test",
+		"type": "String"
+	}]
+}
\ No newline at end of file
diff --git a/org.eclipse.ice.dev/pom.xml b/org.eclipse.ice.dev/pom.xml
index 6e71b30c908c4ac4bed1cc237c1f4a53bc81b25c..e3f118da7f3240ca70b803903687926cb298b541 100644
--- a/org.eclipse.ice.dev/pom.xml
+++ b/org.eclipse.ice.dev/pom.xml
@@ -8,5 +8,6 @@
   <modules>
   	<module>org.eclipse.ice.dev.annotations</module>
   	<module>org.eclipse.ice.dev.annotations.proxytest</module>
+  	<module>org.eclipse.ice.dev.pojofromjson</module>
   </modules>
 </project>
\ No newline at end of file