diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2702ba4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,15 @@
+.settings/
+target/
+
+# Windows
+Thumbs.db
+Desktop.ini
+
+# OSX
+.DS_Store
+
+#Eclipse
+.project
+.metadata
+.classpath
+.settings/
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..b6f7b61
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,46 @@
+
+ 4.0.0
+ gov.nist.healthcare.pcd.pcdtool
+ pcdtool-message-validation
+ 0.0.1-SNAPSHOT
+
+
+
+ joda-time
+ joda-time
+ 2.7
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+
+ log4j
+ log4j
+ 1.2.17
+
+
+ gov.nist.hit.core.hl7v2
+ hit-core-hl7v2-api
+ ${hitcorehl7v2.version}
+
+
+ org.apache.commons
+ commons-lang3
+ 3.4
+
+
+ com.google.guava
+ guava
+ 18.0
+
+
+
+ 1.0.19
+
+
\ No newline at end of file
diff --git a/src/main/java/gov/nist/hit/pcd/custom/CodedElementFormat.java b/src/main/java/gov/nist/hit/pcd/custom/CodedElementFormat.java
new file mode 100644
index 0000000..9414868
--- /dev/null
+++ b/src/main/java/gov/nist/hit/pcd/custom/CodedElementFormat.java
@@ -0,0 +1,72 @@
+package gov.nist.hit.pcd.custom;
+
+
+import hl7.v2.instance.Element;
+import hl7.v2.instance.Query;
+import hl7.v2.instance.Simple;
+import scala.collection.Iterator;
+import scala.collection.immutable.List;
+
+public abstract class CodedElementFormat {
+
+ public boolean isValid(String code) {
+ return true;
+ }
+
+ public abstract String getCodeSystemValue();
+
+ public boolean checkFirstTriplet(List elementList) {
+ if (elementList != null) {
+ Iterator it = elementList.iterator();
+ while (it.hasNext()) {
+ Element element = it.next();
+ // get 3rd component
+ List codeSystemList = Query.queryAsSimple(element,
+ "3[1]").get();
+ String codeSystem = getValue(codeSystemList);
+ if (getCodeSystemValue().equals(codeSystem)) {
+ // get 1st component
+ List identifierList = Query.queryAsSimple(element,
+ "1[1]").get();
+ String identifier = getValue(identifierList);
+ return isValid(identifier);
+ }
+ }
+ }
+ return true;
+ }
+
+ public boolean checkSecondTriplet(List elementList) {
+ if (elementList != null) {
+ Iterator it = elementList.iterator();
+ while (it.hasNext()) {
+ Element element = it.next();
+ // get 3rd component
+ List codeSystemList = Query.queryAsSimple(element,
+ "6[1]").get();
+ String codeSystem = getValue(codeSystemList);
+ if (getCodeSystemValue().equals(codeSystem)) {
+ // get 1st component
+ List identifierList = Query.queryAsSimple(element,
+ "4[1]").get();
+ String identifier = getValue(identifierList);
+ return isValid(identifier);
+ }
+ }
+ }
+ return true;
+ }
+
+ private static String getValue(List simpleElementList) {
+ if (simpleElementList.size() > 1) {
+ throw new IllegalArgumentException("Invalid List size : "
+ + simpleElementList.size());
+ }
+ if (simpleElementList.size() == 0) {
+ return "";
+ }
+ // only get first element
+ return simpleElementList.apply(0).value().raw();
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/gov/nist/hit/pcd/custom/LOINC.java b/src/main/java/gov/nist/hit/pcd/custom/LOINC.java
new file mode 100644
index 0000000..f4dab2b
--- /dev/null
+++ b/src/main/java/gov/nist/hit/pcd/custom/LOINC.java
@@ -0,0 +1,98 @@
+package gov.nist.hit.pcd.custom;
+
+import hl7.v2.instance.Simple;
+import scala.collection.immutable.List;
+
+public class LOINC extends CodedElementFormat {
+
+ private static String codeSystemValue = "LN";
+
+ public String getCodeSystemValue() {
+ return codeSystemValue;
+ }
+
+ /**
+ * Check if a code is a valid LOINC
+ *
+ * @param code
+ * @return true if valid
+ */
+ public boolean isValid(String code) {
+ if (!code.matches("\\d{1,5}-\\d")) {
+ return false;
+ }
+ String extract = code.substring(0, code.indexOf("-"));
+ String checkDigit = mod10(extract);
+ String loinc = String.format("%s-%s", extract, checkDigit);
+ return code.equals(loinc);
+ }
+
+ /**
+ * Mod10 algorithm for LOINC
+ *
+ * @param code
+ * @return the mod10 String
+ */
+ private static String mod10(String code) {
+ if (!code.matches("\\d+")) {
+ return null;
+ }
+ if (code.length() > 5) {
+ return null;
+ }
+ // if length < 5, add leading "0"
+ StringBuffer input = new StringBuffer(code);
+ while (input.length() < 5) {
+ input.insert(0, "0");
+ }
+
+ // 1. Using the number 12345, assign positions to the digits, from right
+ // to left.
+
+ // 2. Take the odd digit positions counting from the right (1st, 3rd,
+ // 5th, etc.)
+ StringBuffer odd = new StringBuffer();
+ for (int i = 0; 2 * i < input.length(); i++) {
+ odd.insert(0, input.charAt(2 * i));
+ }
+
+ // 3.Multiply by 2.
+ int odd2 = Integer.parseInt(odd.toString()) * 2;
+
+ // 4. Take the even digit positions starting from the right (2nd, 4th,
+ // etc.).
+ StringBuffer even = new StringBuffer();
+ for (int i = 0; 2 * i + 1 < input.length(); i++) {
+ even.insert(0, input.charAt(2 * i + 1));
+ }
+
+ // 5.Append (4) to the front of the results of (3).
+ even.append(odd2);
+
+ // 6. Add the digits of (5) together.
+ double add = 0;
+ for (int i = 0; i < even.length(); i++) {
+ add = add + Integer.parseInt(even.substring(i, i + 1));
+ }
+
+ // 7. Find the next highest multiple of 10.
+ double multiple = Math.ceil(add / 10) * 10;
+
+ // 8. Subtract (6) from (7).
+ Long result = Math.round(multiple - add);
+
+ return result.toString();
+ }
+
+ private String getValue(List simpleElementList) {
+ if (simpleElementList.size() > 1) {
+ throw new IllegalArgumentException("Invalid List size : "
+ + simpleElementList.size());
+ }
+ if (simpleElementList.size() == 0) {
+ return "";
+ }
+ // only get first element
+ return simpleElementList.apply(0).value().raw();
+ }
+}
\ No newline at end of file