NIFI-506: Initial import of HL7 work

Project: http://git-wip-us.apache.org/repos/asf/incubator-nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-nifi/commit/45416dc6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-nifi/tree/45416dc6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-nifi/diff/45416dc6

Branch: refs/heads/NIFI-271
Commit: 45416dc66bc212bacf5a8429e4ae2ae880c0672c
Parents: e8fde85
Author: Mark Payne <marka...@hotmail.com>
Authored: Thu Apr 9 17:54:33 2015 -0400
Committer: Mark Payne <marka...@hotmail.com>
Committed: Thu Apr 9 17:54:33 2015 -0400

----------------------------------------------------------------------
 .../nifi-hl7-query-language/.gitignore          |   3 +
 .../nifi-hl7-query-language/pom.xml             | 115 ++++++
 .../apache/nifi/hl7/query/antlr/HL7QueryLexer.g | 156 +++++++
 .../nifi/hl7/query/antlr/HL7QueryParser.g       |  91 ++++
 .../org/apache/nifi/hl7/hapi/EmptyField.java    |  37 ++
 .../org/apache/nifi/hl7/hapi/HapiField.java     |  83 ++++
 .../org/apache/nifi/hl7/hapi/HapiMessage.java   |  94 +++++
 .../org/apache/nifi/hl7/hapi/HapiSegment.java   |  69 ++++
 .../apache/nifi/hl7/hapi/SingleValueField.java  |  42 ++
 .../java/org/apache/nifi/hl7/io/HL7Reader.java  |  27 ++
 .../hl7/io/exception/InvalidHL7Exception.java   |  40 ++
 .../org/apache/nifi/hl7/model/HL7Component.java |  24 ++
 .../org/apache/nifi/hl7/model/HL7Field.java     |  21 +
 .../org/apache/nifi/hl7/model/HL7Message.java   |  27 ++
 .../org/apache/nifi/hl7/model/HL7Segment.java   |  27 ++
 .../org/apache/nifi/hl7/query/Declaration.java  |  29 ++
 .../org/apache/nifi/hl7/query/HL7Query.java     | 412 +++++++++++++++++++
 .../org/apache/nifi/hl7/query/QueryResult.java  |  29 ++
 .../org/apache/nifi/hl7/query/ResultHit.java    |  25 ++
 .../org/apache/nifi/hl7/query/Selection.java    |  37 ++
 .../hl7/query/evaluator/BooleanEvaluator.java   |  24 ++
 .../nifi/hl7/query/evaluator/Evaluator.java     |  27 ++
 .../hl7/query/evaluator/IntegerEvaluator.java   |  26 ++
 .../hl7/query/evaluator/StringEvaluator.java    |  25 ++
 .../comparison/AbstractComparisonEvaluator.java | 106 +++++
 .../comparison/AbstractNumericComparison.java   |  67 +++
 .../evaluator/comparison/EqualsEvaluator.java   |  32 ++
 .../comparison/GreaterThanEvaluator.java        |  34 ++
 .../comparison/GreaterThanOrEqualEvaluator.java |  34 ++
 .../evaluator/comparison/IsNullEvaluator.java   |  69 ++++
 .../evaluator/comparison/LessThanEvaluator.java |  31 ++
 .../comparison/LessThanOrEqualEvaluator.java    |  31 ++
 .../comparison/NotEqualsEvaluator.java          |  32 ++
 .../evaluator/comparison/NotEvaluator.java      |  36 ++
 .../evaluator/comparison/NotNullEvaluator.java  |  65 +++
 .../literal/IntegerLiteralEvaluator.java        |  36 ++
 .../literal/StringLiteralEvaluator.java         |  35 ++
 .../hl7/query/evaluator/logic/AndEvaluator.java |  43 ++
 .../hl7/query/evaluator/logic/OrEvaluator.java  |  43 ++
 .../message/DeclaredReferenceEvaluator.java     |  42 ++
 .../query/evaluator/message/DotEvaluator.java   |  88 ++++
 .../query/evaluator/message/FieldEvaluator.java |  67 +++
 .../evaluator/message/MessageEvaluator.java     |  34 ++
 .../evaluator/message/SegmentEvaluator.java     |  51 +++
 .../exception/HL7QueryParsingException.java     |  37 ++
 .../nifi/hl7/query/result/MissedResult.java     |  56 +++
 .../hl7/query/result/StandardQueryResult.java   |  69 ++++
 .../hl7/query/result/StandardResultHit.java     |  41 ++
 .../org/apache/nifi/hl7/query/TestHL7Query.java | 352 ++++++++++++++++
 .../src/test/resources/hyperglycemia            |   5 +
 .../src/test/resources/hypoglycemia             |   5 +
 .../src/test/resources/metabolic-panel          |  23 ++
 .../resources/unsolicited-vaccine-update-long   |  16 +
 .../resources/unsolicited-vaccine-update-short  |   4 +
 .../src/test/resources/vaccine-query            |   3 +
 .../src/test/resources/vaers-message-long       |  60 +++
 .../nifi-hl7-bundle/nifi-hl7-nar/pom.xml        |  36 ++
 .../nifi-hl7-processors/.gitignore              |   1 +
 .../nifi-hl7-bundle/nifi-hl7-processors/pom.xml | 106 +++++
 .../processors/hl7/ExtractHL7Attributes.java    | 247 +++++++++++
 .../apache/nifi/processors/hl7/RouteHL7.java    | 217 ++++++++++
 .../org.apache.nifi.processor.Processor         |  16 +
 .../hl7/TestExtractHL7Attributes.java           |  48 +++
 .../src/test/resources/1.hl7                    |  16 +
 .../src/test/resources/hypoglycemia.hl7         |   5 +
 nifi/nifi-nar-bundles/nifi-hl7-bundle/pom.xml   |  33 ++
 66 files changed, 3862 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/.gitignore
----------------------------------------------------------------------
diff --git a/nifi/nifi-commons/nifi-hl7-query-language/.gitignore 
b/nifi/nifi-commons/nifi-hl7-query-language/.gitignore
new file mode 100644
index 0000000..e91d5c4
--- /dev/null
+++ b/nifi/nifi-commons/nifi-hl7-query-language/.gitignore
@@ -0,0 +1,3 @@
+/target/
+/target/
+/target/

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/pom.xml
----------------------------------------------------------------------
diff --git a/nifi/nifi-commons/nifi-hl7-query-language/pom.xml 
b/nifi/nifi-commons/nifi-hl7-query-language/pom.xml
new file mode 100644
index 0000000..447a88b
--- /dev/null
+++ b/nifi/nifi-commons/nifi-hl7-query-language/pom.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements. See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License. You may obtain a copy of the License at
+  http://www.apache.org/licenses/LICENSE-2.0
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+       <modelVersion>4.0.0</modelVersion>
+       
+       <parent>
+               <groupId>org.apache.nifi</groupId>
+               <artifactId>nifi-commons</artifactId>
+               <version>0.1.0-incubating-SNAPSHOT</version>
+       </parent>
+       
+       <artifactId>nifi-hl7-query-language</artifactId>
+       <packaging>jar</packaging>
+
+       <name>NiFi Health Level 7 (HL7) Query Language</name>
+
+       <build>
+               <plugins>
+                       <plugin>
+                               <artifactId>maven-compiler-plugin</artifactId>
+                               <configuration>
+                                       <source>1.7</source>
+                                       <target>1.7</target>
+                               </configuration>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.antlr</groupId>
+                               <artifactId>antlr3-maven-plugin</artifactId>
+                               <executions>
+                                       <execution>
+                                               <goals>
+                                                       <goal>antlr</goal>
+                                               </goals>
+                                       </execution>
+                               </executions>
+                       </plugin>
+               </plugins>
+       </build>
+
+       <dependencies>
+               <dependency>
+                       <groupId>org.antlr</groupId>
+                       <artifactId>antlr-runtime</artifactId>
+                       <version>3.5.2</version>
+               </dependency>
+               
+               <!-- HAPI to parse v2 messages -->
+               <dependency>
+                       <groupId>ca.uhn.hapi</groupId>
+                       <artifactId>hapi-base</artifactId>
+                       <version>2.2</version>
+               </dependency>
+               <dependency>
+                       <groupId>ca.uhn.hapi</groupId>
+                       <artifactId>hapi-structures-v21</artifactId>
+                       <version>2.2</version>
+               </dependency>
+               <dependency>
+                       <groupId>ca.uhn.hapi</groupId>
+                       <artifactId>hapi-structures-v22</artifactId>
+                       <version>2.2</version>
+               </dependency>
+               <dependency>
+                       <groupId>ca.uhn.hapi</groupId>
+                       <artifactId>hapi-structures-v23</artifactId>
+                       <version>2.2</version>
+               </dependency>
+               <dependency>
+                       <groupId>ca.uhn.hapi</groupId>
+                       <artifactId>hapi-structures-v231</artifactId>
+                       <version>2.2</version>
+               </dependency>
+               <dependency>
+                       <groupId>ca.uhn.hapi</groupId>
+                       <artifactId>hapi-structures-v24</artifactId>
+                       <version>2.2</version>
+               </dependency>
+               <dependency>
+                       <groupId>ca.uhn.hapi</groupId>
+                       <artifactId>hapi-structures-v25</artifactId>
+                       <version>2.2</version>
+               </dependency>
+               <dependency>
+                       <groupId>ca.uhn.hapi</groupId>
+                       <artifactId>hapi-structures-v251</artifactId>
+                       <version>2.2</version>
+               </dependency>
+               <dependency>
+                       <groupId>ca.uhn.hapi</groupId>
+                       <artifactId>hapi-structures-v26</artifactId>
+                       <version>2.2</version>
+               </dependency>
+
+
+               <dependency>
+                       <groupId>junit</groupId>
+                       <artifactId>junit</artifactId>
+                       <scope>test</scope>
+               </dependency>
+       </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/antlr3/org/apache/nifi/hl7/query/antlr/HL7QueryLexer.g
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/antlr3/org/apache/nifi/hl7/query/antlr/HL7QueryLexer.g
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/antlr3/org/apache/nifi/hl7/query/antlr/HL7QueryLexer.g
new file mode 100644
index 0000000..7fe3386
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/antlr3/org/apache/nifi/hl7/query/antlr/HL7QueryLexer.g
@@ -0,0 +1,156 @@
+lexer grammar HL7QueryLexer;
+
+@header {
+       package org.apache.nifi.hl7.query.antlr;
+       import org.apache.nifi.hl7.query.exception.HL7QueryParsingException;
+}
+
+@rulecatch {
+  catch(final Exception e) {
+    throw new HL7QueryParsingException(e);
+  }
+}
+
+@members {
+  public void displayRecognitionError(String[] tokenNames, 
RecognitionException e) {
+    final StringBuilder sb = new StringBuilder();
+    if ( e.token == null ) {
+       sb.append("Unrecognized token ");
+    } else {
+       sb.append("Unexpected token '").append(e.token.getText()).append("' ");
+    }
+    sb.append("at line ").append(e.line);
+    if ( e.approximateLineInfo ) {
+       sb.append(" (approximately)");
+    }
+    sb.append(", column ").append(e.charPositionInLine);
+    sb.append(". Query: ").append(e.input.toString());
+    
+    throw new HL7QueryParsingException(sb.toString());
+  }
+
+  public void recover(RecognitionException e) {
+       final StringBuilder sb = new StringBuilder();
+    if ( e.token == null ) {
+       sb.append("Unrecognized token ");
+    } else {
+       sb.append("Unexpected token '").append(e.token.getText()).append("' ");
+    }
+    sb.append("at line ").append(e.line);
+    if ( e.approximateLineInfo ) {
+       sb.append(" (approximately)");
+    }
+    sb.append(", column ").append(e.charPositionInLine);
+    sb.append(". Query: ").append(e.input.toString());
+    
+    throw new HL7QueryParsingException(sb.toString());
+  } 
+}
+
+
+// PUNCTUATION & SPECIAL CHARACTERS
+WHITESPACE : (' '|'\t'|'\n'|'\r')+ { $channel = HIDDEN; };
+COMMENT : '#' ( ~('\n') )* '\n' { $channel = HIDDEN; };
+
+LPAREN : '(';
+RPAREN : ')';
+LBRACE  : '{';
+RBRACE  : '}';
+COLON  : ':';
+COMMA  : ',';
+DOT            : '.';
+SEMICOLON : ';';
+
+
+
+// OPERATORS
+EQUALS         : '=';
+NOT_EQUALS     : '!=';
+GT                     : '>';
+GE                     : '>=';
+LT                     : '<';
+LE                     : '<=';
+REGEX          : 'MATCHES REGEX';
+LIKE           : 'LIKE';
+IS_NULL                : 'IS NULL';
+NOT_NULL       : 'NOT NULL';
+
+
+// KEYWORDS
+AND                    : 'AND';
+OR                     : 'OR';
+NOT                    : 'NOT';
+
+TRUE   : 'true';
+FALSE  : 'false';
+
+SELECT         : 'select' | 'SELECT';
+DECLARE                : 'declare' | 'DECLARE';
+OPTIONAL       : 'optional' | 'OPTIONAL';
+REQUIRED       : 'required' | 'REQUIRED';
+AS                     : 'as' | 'AS';
+WHERE          : 'where' | 'WHERE';
+
+MESSAGE        : 'MESSAGE' | 'message';
+SEGMENT        : 'SEGMENT' | 'segment';
+
+
+SEGMENT_NAME : LETTER ALPHA_NUMERIC ALPHA_NUMERIC;
+
+
+NUMBER : ('0'..'9')+;
+fragment LETTER : 'A'..'Z';
+fragment ALPHA_NUMERIC : 'A'..'Z' | '0'..'9';
+
+
+// STRINGS
+STRING_LITERAL
+@init{StringBuilder lBuf = new StringBuilder();}
+       :
+               (
+                       '"'
+                               (
+                                       escaped=ESC {lBuf.append(getText());} |
+                                       normal = ~( '"' | '\\' | '\n' | '\r' | 
'\t' ) { lBuf.appendCodePoint(normal);} 
+                               )*
+                       '"'
+               )
+               {
+                       setText(lBuf.toString());
+               }
+               |
+               (
+                       '\''
+                               (
+                                       escaped=ESC {lBuf.append(getText());} |
+                                       normal = ~( '\'' | '\\' | '\n' | '\r' | 
'\t' ) { lBuf.appendCodePoint(normal);} 
+                               )*
+                       '\''
+               )
+               {
+                       setText(lBuf.toString());
+               }
+               ;
+
+
+fragment
+ESC
+       :       '\\'
+               (
+                               '"'             { setText("\""); }
+                       |       '\''    { setText("\'"); }
+                       |       'r'             { setText("\r"); }
+                       |       'n'             { setText("\n"); }
+                       |       't'             { setText("\t"); }
+                       |       '\\'    { setText("\\\\"); }
+                       |       nextChar = ~('"' | '\'' | 'r' | 'n' | 't' | 
'\\')               
+                               {
+                                       StringBuilder lBuf = new 
StringBuilder(); lBuf.append("\\\\").appendCodePoint(nextChar); 
setText(lBuf.toString());
+                               }
+               )
+       ;
+
+IDENTIFIER : (
+                                 ~('$' | '{' | '}' | '(' | ')' | '[' | ']' | 
',' | ':' | ';' | '/' | '*' | '\'' | ' ' | '\t' | '\r' | '\n' | '0'..'9' | '.')
+                                 ~('$' | '{' | '}' | '(' | ')' | '[' | ']' | 
',' | ':' | ';' | '/' | '*' | '\'' | ' ' | '\t' | '\r' | '\n' | '.')*
+                                );

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/antlr3/org/apache/nifi/hl7/query/antlr/HL7QueryParser.g
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/antlr3/org/apache/nifi/hl7/query/antlr/HL7QueryParser.g
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/antlr3/org/apache/nifi/hl7/query/antlr/HL7QueryParser.g
new file mode 100644
index 0000000..4d8d13c
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/antlr3/org/apache/nifi/hl7/query/antlr/HL7QueryParser.g
@@ -0,0 +1,91 @@
+parser grammar HL7QueryParser;
+
+options {
+       output=AST;
+       tokenVocab=HL7QueryLexer;
+}
+
+tokens {
+       QUERY;
+       DECLARATION;
+}
+
+@header {
+       package org.apache.nifi.hl7.query.antlr;
+       import org.apache.nifi.hl7.query.exception.HL7QueryParsingException;
+}
+
+@members {
+  public void displayRecognitionError(String[] tokenNames, 
RecognitionException e) {
+       final StringBuilder sb = new StringBuilder();
+    if ( e.token == null ) {
+       sb.append("Unrecognized token ");
+    } else {
+       sb.append("Unexpected token '").append(e.token.getText()).append("' ");
+    }
+    sb.append("at line ").append(e.line);
+    if ( e.approximateLineInfo ) {
+       sb.append(" (approximately)");
+    }
+    sb.append(", column ").append(e.charPositionInLine);
+    sb.append(". Query: ").append(e.input.toString());
+    
+    throw new HL7QueryParsingException(sb.toString());
+  }
+
+  public void recover(final RecognitionException e) {
+       final StringBuilder sb = new StringBuilder();
+    if ( e.token == null ) {
+       sb.append("Unrecognized token ");
+    } else {
+       sb.append("Unexpected token '").append(e.token.getText()).append("' ");
+    }
+    sb.append("at line ").append(e.line);
+    if ( e.approximateLineInfo ) {
+       sb.append(" (approximately)");
+    }
+    sb.append(", column ").append(e.charPositionInLine);
+    sb.append(". Query: ").append(e.input.toString());
+    
+    throw new HL7QueryParsingException(sb.toString());
+  } 
+}
+
+
+declareClause : DECLARE^ declaration (COMMA! declaration)*;
+
+requiredOrOptional : REQUIRED | OPTIONAL;
+declaration : IDENTIFIER AS requiredOrOptional SEGMENT_NAME ->
+       ^(DECLARATION IDENTIFIER requiredOrOptional SEGMENT_NAME);
+
+
+selectClause : SELECT^ selectableClause;
+selectableClause : selectable (COMMA! selectable)*;
+selectable : (MESSAGE | ref | field)^ (AS! IDENTIFIER^)?;
+
+
+whereClause : WHERE^ conditions;
+
+conditions : condition ((AND^ | OR^) condition)*;
+
+condition : NOT^ condition | LPAREN! conditions RPAREN! | evaluation;
+
+evaluation : expression
+                        (
+                               unaryOperator^
+                               | (binaryOperator^ expression)
+                        );
+
+expression : (LPAREN! expr RPAREN!) | expr;
+expr : ref | field | STRING_LITERAL | NUMBER;
+
+unaryOperator : IS_NULL | NOT_NULL;
+binaryOperator : EQUALS | NOT_EQUALS | LT | GT | LE | GE;
+
+ref : (SEGMENT_NAME | IDENTIFIER);
+field : ref DOT^ NUMBER 
+       (DOT^ NUMBER (DOT^ NUMBER (DOT^ NUMBER)?)?)?;
+
+
+query : declareClause? selectClause whereClause? EOF ->
+       ^(QUERY declareClause? selectClause whereClause?);

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/hapi/EmptyField.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/hapi/EmptyField.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/hapi/EmptyField.java
new file mode 100644
index 0000000..be645e5
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/hapi/EmptyField.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.hapi;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.nifi.hl7.model.HL7Component;
+import org.apache.nifi.hl7.model.HL7Field;
+
+public class EmptyField implements HL7Field {
+
+       @Override
+       public String getValue() {
+               return null;
+       }
+
+       @Override
+       public List<HL7Component> getComponents() {
+               return Collections.emptyList();
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/hapi/HapiField.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/hapi/HapiField.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/hapi/HapiField.java
new file mode 100644
index 0000000..056b6b6
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/hapi/HapiField.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.hapi;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.nifi.hl7.model.HL7Component;
+import org.apache.nifi.hl7.model.HL7Field;
+
+import ca.uhn.hl7v2.model.Composite;
+import ca.uhn.hl7v2.model.ExtraComponents;
+import ca.uhn.hl7v2.model.Primitive;
+import ca.uhn.hl7v2.model.Type;
+import ca.uhn.hl7v2.model.Varies;
+import ca.uhn.hl7v2.parser.EncodingCharacters;
+import ca.uhn.hl7v2.parser.PipeParser;
+
+public class HapiField implements HL7Field, HL7Component {
+       private final String value;
+       private final List<HL7Component> components;
+       
+       public HapiField(final Type type) {
+               this.value = PipeParser.encode(type, 
EncodingCharacters.defaultInstance());
+               
+               final List<HL7Component> componentList = new ArrayList<>();
+               if ( type instanceof Composite ) {
+                       final Composite composite = (Composite) type;
+                       
+                       for ( final Type component : composite.getComponents() 
) {
+                               componentList.add(new HapiField(component));
+                       }
+               }
+               
+               final ExtraComponents extra = type.getExtraComponents();
+               if ( extra != null && extra.numComponents() > 0 ) {
+                       final String singleFieldValue;
+                       if ( type instanceof Primitive ) {
+                               singleFieldValue = ((Primitive) 
type).getValue();
+                       } else {
+                               singleFieldValue = this.value;
+                       }
+                       componentList.add(new 
SingleValueField(singleFieldValue));
+                       
+                       for (int i=0; i < extra.numComponents(); i++) {
+                               final Varies varies = extra.getComponent(i);
+                               componentList.add(new HapiField(varies));
+                       }
+               }
+               
+               this.components = Collections.unmodifiableList(componentList);
+       }
+       
+       @Override
+       public String getValue() {
+               return value;
+       }
+
+       @Override
+       public List<HL7Component> getComponents() {
+               return components;
+       }
+       
+       @Override
+       public String toString() {
+               return value;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/hapi/HapiMessage.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/hapi/HapiMessage.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/hapi/HapiMessage.java
new file mode 100644
index 0000000..ddd28b2
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/hapi/HapiMessage.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.hapi;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.nifi.hl7.model.HL7Message;
+import org.apache.nifi.hl7.model.HL7Segment;
+
+import ca.uhn.hl7v2.HL7Exception;
+import ca.uhn.hl7v2.model.Group;
+import ca.uhn.hl7v2.model.Message;
+import ca.uhn.hl7v2.model.Segment;
+import ca.uhn.hl7v2.model.Structure;
+
+public class HapiMessage implements HL7Message {
+       private final Message message;
+       private final List<HL7Segment> allSegments;
+       private final Map<String, List<HL7Segment>> segmentMap;
+       
+       public HapiMessage(final Message message) throws HL7Exception {
+               this.message = message;
+               
+               allSegments = new ArrayList<>();
+               populateSegments(message, allSegments);
+               
+               segmentMap = new HashMap<>();
+               for ( final HL7Segment segment : allSegments ) {
+                       final String segmentName = segment.getName();
+                       List<HL7Segment> segmentList = 
segmentMap.get(segmentName);
+                       if ( segmentList == null ) {
+                               segmentList = new ArrayList<>();
+                               segmentMap.put(segmentName, segmentList);
+                       }
+                       
+                       segmentList.add(segment);
+               }
+       }
+       
+       private void populateSegments(final Group group, final List<HL7Segment> 
segments) throws HL7Exception {
+               for ( final String structureName : group.getNames() ) {
+                       final Structure[] structures = 
group.getAll(structureName);
+                       if ( group.isGroup(structureName) ) {
+                               for ( final Structure structure : structures ) {
+                                       populateSegments((Group) structure, 
segments);
+                               }
+                       } else {
+                               for ( final Structure structure : structures ) {
+                                       final Segment segment = (Segment) 
structure;
+                                       final HapiSegment hapiSegment = new 
HapiSegment(segment);
+                                       segments.add(hapiSegment);
+                               }
+                       }
+               }
+       }
+       
+       @Override
+       public List<HL7Segment> getSegments() {
+               return Collections.unmodifiableList(allSegments);
+       }
+
+       @Override
+       public List<HL7Segment> getSegments(final String segmentType) {
+               final List<HL7Segment> segments = segmentMap.get(segmentType);
+               if ( segments == null ) {
+                       return Collections.emptyList();
+               }
+               
+               return Collections.unmodifiableList(segments);
+       }
+
+       @Override
+       public String toString() {
+               return message.toString();
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/hapi/HapiSegment.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/hapi/HapiSegment.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/hapi/HapiSegment.java
new file mode 100644
index 0000000..d50afdb
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/hapi/HapiSegment.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.hapi;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.nifi.hl7.model.HL7Field;
+import org.apache.nifi.hl7.model.HL7Segment;
+
+import ca.uhn.hl7v2.HL7Exception;
+import ca.uhn.hl7v2.model.Segment;
+import ca.uhn.hl7v2.model.Type;
+
+public class HapiSegment implements HL7Segment {
+       private final Segment segment;
+       private final List<HL7Field> fields;
+       
+       public HapiSegment(final Segment segment) throws HL7Exception {
+               this.segment = segment;
+               
+               final List<HL7Field> fieldList = new ArrayList<>();
+               for (int i=1; i <= segment.numFields(); i++) {
+                       final Type[] types = segment.getField(i);
+
+                       if ( types == null || types.length == 0 ) {
+                               fieldList.add(new EmptyField());
+                               continue;
+                       }
+                       
+                       for ( final Type type : types ) {
+                               fieldList.add(new HapiField(type));
+                       }
+               }
+               
+               this.fields = Collections.unmodifiableList(fieldList);
+       }
+       
+       
+       @Override
+       public String getName() {
+               return segment.getName();
+       }
+
+       @Override
+       public List<HL7Field> getFields() {
+               return fields;
+       }
+
+       @Override
+       public String toString() {
+               return segment.toString();
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/hapi/SingleValueField.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/hapi/SingleValueField.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/hapi/SingleValueField.java
new file mode 100644
index 0000000..ed99077
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/hapi/SingleValueField.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.hapi;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.nifi.hl7.model.HL7Component;
+import org.apache.nifi.hl7.model.HL7Field;
+
+public class SingleValueField implements HL7Field {
+       private final String value;
+       
+       public SingleValueField(final String value) {
+               this.value = value;
+       }
+       
+       @Override
+       public String getValue() {
+               return value;
+       }
+
+       @Override
+       public List<HL7Component> getComponents() {
+               return Collections.emptyList();
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/io/HL7Reader.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/io/HL7Reader.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/io/HL7Reader.java
new file mode 100644
index 0000000..e7b31a4
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/io/HL7Reader.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.io;
+
+import java.io.IOException;
+
+import org.apache.nifi.hl7.model.HL7Message;
+
+public interface HL7Reader {
+
+       HL7Message nextMessage() throws IOException;
+       
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/io/exception/InvalidHL7Exception.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/io/exception/InvalidHL7Exception.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/io/exception/InvalidHL7Exception.java
new file mode 100644
index 0000000..669f40c
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/io/exception/InvalidHL7Exception.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.io.exception;
+
+import java.io.IOException;
+
+public class InvalidHL7Exception extends IOException {
+       private static final long serialVersionUID = -5675416667224562441L;
+
+       public InvalidHL7Exception() {
+               super();
+       }
+
+       public InvalidHL7Exception(String message, Throwable cause) {
+               super(message, cause);
+       }
+
+       public InvalidHL7Exception(String message) {
+               super(message);
+       }
+
+       public InvalidHL7Exception(Throwable cause) {
+               super(cause);
+       }
+       
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/model/HL7Component.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/model/HL7Component.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/model/HL7Component.java
new file mode 100644
index 0000000..cf35504
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/model/HL7Component.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.model;
+
+import java.util.List;
+
+public interface HL7Component {
+       String getValue();
+       List<HL7Component> getComponents();
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/model/HL7Field.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/model/HL7Field.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/model/HL7Field.java
new file mode 100644
index 0000000..4086e58
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/model/HL7Field.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.model;
+
+
+public interface HL7Field extends HL7Component {
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/model/HL7Message.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/model/HL7Message.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/model/HL7Message.java
new file mode 100644
index 0000000..dd9c2a9
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/model/HL7Message.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.model;
+
+import java.util.List;
+
+public interface HL7Message {
+
+       List<HL7Segment> getSegments();
+       
+       List<HL7Segment> getSegments(String segmentType);
+       
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/model/HL7Segment.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/model/HL7Segment.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/model/HL7Segment.java
new file mode 100644
index 0000000..de5aaa1
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/model/HL7Segment.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.model;
+
+import java.util.List;
+
+public interface HL7Segment {
+
+       String getName();
+       
+       List<HL7Field> getFields();
+       
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/Declaration.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/Declaration.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/Declaration.java
new file mode 100644
index 0000000..0903cc8
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/Declaration.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.query;
+
+import org.apache.nifi.hl7.model.HL7Message;
+
+public interface Declaration {
+
+       String getAlias();
+       
+       boolean isRequired();
+       
+       Object getDeclaredValue(HL7Message message);
+       
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/HL7Query.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/HL7Query.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/HL7Query.java
new file mode 100644
index 0000000..a036106
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/HL7Query.java
@@ -0,0 +1,412 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.query;
+
+import static org.apache.nifi.hl7.query.antlr.HL7QueryParser.*;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.antlr.runtime.ANTLRStringStream;
+import org.antlr.runtime.CharStream;
+import org.antlr.runtime.CommonTokenStream;
+import org.antlr.runtime.tree.Tree;
+import org.apache.nifi.hl7.model.HL7Message;
+import org.apache.nifi.hl7.query.evaluator.BooleanEvaluator;
+import org.apache.nifi.hl7.query.evaluator.Evaluator;
+import org.apache.nifi.hl7.query.evaluator.IntegerEvaluator;
+import org.apache.nifi.hl7.query.evaluator.comparison.EqualsEvaluator;
+import org.apache.nifi.hl7.query.evaluator.comparison.GreaterThanEvaluator;
+import 
org.apache.nifi.hl7.query.evaluator.comparison.GreaterThanOrEqualEvaluator;
+import org.apache.nifi.hl7.query.evaluator.comparison.IsNullEvaluator;
+import org.apache.nifi.hl7.query.evaluator.comparison.LessThanEvaluator;
+import org.apache.nifi.hl7.query.evaluator.comparison.LessThanOrEqualEvaluator;
+import org.apache.nifi.hl7.query.evaluator.comparison.NotEqualsEvaluator;
+import org.apache.nifi.hl7.query.evaluator.comparison.NotEvaluator;
+import org.apache.nifi.hl7.query.evaluator.comparison.NotNullEvaluator;
+import org.apache.nifi.hl7.query.evaluator.literal.IntegerLiteralEvaluator;
+import org.apache.nifi.hl7.query.evaluator.literal.StringLiteralEvaluator;
+import org.apache.nifi.hl7.query.evaluator.logic.AndEvaluator;
+import org.apache.nifi.hl7.query.evaluator.logic.OrEvaluator;
+import org.apache.nifi.hl7.query.evaluator.message.DeclaredReferenceEvaluator;
+import org.apache.nifi.hl7.query.evaluator.message.DotEvaluator;
+import org.apache.nifi.hl7.query.evaluator.message.MessageEvaluator;
+import org.apache.nifi.hl7.query.evaluator.message.SegmentEvaluator;
+import org.apache.nifi.hl7.query.exception.HL7QueryParsingException;
+import org.apache.nifi.hl7.query.result.MissedResult;
+import org.apache.nifi.hl7.query.result.StandardQueryResult;
+
+import org.apache.nifi.hl7.query.antlr.HL7QueryLexer;
+import org.apache.nifi.hl7.query.antlr.HL7QueryParser;
+
+
+public class HL7Query {
+       private final Tree tree;
+       private final String query;
+       private final Set<Declaration> declarations = new HashSet<>();
+       
+       private final List<Selection> selections;
+       private final BooleanEvaluator whereEvaluator;
+       
+       private HL7Query(final Tree tree, final String query) {
+               this.tree = tree;
+               this.query = query;
+
+               List<Selection> select = null;
+               BooleanEvaluator where = null;
+               for (int i=0; i < tree.getChildCount(); i++) {
+                       final Tree child = tree.getChild(i);
+                       
+                       switch (child.getType()) {
+                               case DECLARE:
+                                       processDeclare(child);
+                                       break;
+                               case SELECT:
+                                       select = processSelect(child);
+                                       break;
+                               case WHERE:
+                                       where = processWhere(child);
+                                       break;
+                               default:
+                                       throw new 
HL7QueryParsingException("Found unexpected clause at root level: " + 
tree.getText());
+                       }
+               }
+               
+               this.whereEvaluator = where;
+               this.selections = select;
+       }
+       
+       private void processDeclare(final Tree declare) {
+               for (int i=0; i < declare.getChildCount(); i++) {
+                       final Tree declarationTree = declare.getChild(i);
+                       
+                       final String identifier = 
declarationTree.getChild(0).getText();
+                       final Tree requiredOrOptionalTree = 
declarationTree.getChild(1);
+                       final boolean required = 
requiredOrOptionalTree.getType() == REQUIRED;
+                       
+                       final String segmentName = 
declarationTree.getChild(2).getText();
+                       
+                       final Declaration declaration = new Declaration() {
+                               @Override
+                               public String getAlias() {
+                                       return identifier;
+                               }
+
+                               @Override
+                               public boolean isRequired() {
+                                       return required;
+                               }
+
+                               @Override
+                               public Object getDeclaredValue(final HL7Message 
message) {
+                                       if ( message == null ) {
+                                               return null;
+                                       }
+                                       
+                                       return message.getSegments(segmentName);
+                               }
+                       };
+                       
+                       declarations.add(declaration);
+               }
+       }
+
+       private List<Selection> processSelect(final Tree select) {
+               final List<Selection> selections = new ArrayList<>();
+
+               for (int i=0; i < select.getChildCount(); i++) {
+                       final Tree selectable = select.getChild(i);
+                       
+                       final String alias = getSelectedName(selectable);
+                       final Evaluator<?> selectionEvaluator = 
buildReferenceEvaluator(selectable);
+                       final Selection selection = new 
Selection(selectionEvaluator, alias);
+                       selections.add(selection);
+               }
+               
+               return selections;
+       }
+       
+       
+       private String getSelectedName(final Tree selectable) {
+               if ( selectable.getChildCount() == 0 ) {
+                       return selectable.getText();
+               } else if (selectable.getType() == DOT ) {
+                       return getSelectedName(selectable.getChild(0)) + "." + 
getSelectedName(selectable.getChild(1));
+               } else {
+                       return selectable.getChild(selectable.getChildCount() - 
1).getText();
+               }
+       }
+       
+
+       private BooleanEvaluator processWhere(final Tree where) {
+               return buildBooleanEvaluator(where.getChild(0));
+       }
+       
+
+       private Evaluator<?> buildReferenceEvaluator(final Tree tree) {
+               switch (tree.getType()) {
+                       case MESSAGE:
+                               return new MessageEvaluator();
+                       case SEGMENT_NAME:
+                               return new SegmentEvaluator(new 
StringLiteralEvaluator(tree.getText()));
+                       case IDENTIFIER:
+                               return new DeclaredReferenceEvaluator(new 
StringLiteralEvaluator(tree.getText()));
+                       case DOT:
+                               final Tree firstChild = tree.getChild(0);
+                               final Tree secondChild = tree.getChild(1);
+                               return new 
DotEvaluator(buildReferenceEvaluator(firstChild), 
buildIntegerEvaluator(secondChild));
+                       case STRING_LITERAL:
+                               return new 
StringLiteralEvaluator(tree.getText());
+                       case NUMBER:
+                               return new 
IntegerLiteralEvaluator(Integer.parseInt(tree.getText()));
+                       default:
+                               throw new HL7QueryParsingException("Failed to 
build evaluator for " + tree.getText());
+               }
+       }
+       
+       
+       private IntegerEvaluator buildIntegerEvaluator(final Tree tree) {
+               switch (tree.getType()) {
+                       case NUMBER:
+                               return new 
IntegerLiteralEvaluator(Integer.parseInt(tree.getText()));
+                       default:
+                               throw new HL7QueryParsingException("Failed to 
build Integer Evaluator for " + tree.getText());
+               }
+       }
+       
+       
+       private BooleanEvaluator buildBooleanEvaluator(final Tree tree) {
+               // TODO: add Date comparisons
+               // LT/GT/GE/GE should allow for dates based on Field's Type
+               // BETWEEN
+               // DATE('2015/01/01')
+               // DATE('2015/01/01 12:00:00')
+               // DATE('24 HOURS AGO')
+               // DATE('YESTERDAY')
+               
+               switch (tree.getType()) {
+                       case EQUALS:
+                               return new 
EqualsEvaluator(buildReferenceEvaluator(tree.getChild(0)), 
buildReferenceEvaluator(tree.getChild(1)));
+                       case NOT_EQUALS:
+                               return new 
NotEqualsEvaluator(buildReferenceEvaluator(tree.getChild(0)), 
buildReferenceEvaluator(tree.getChild(1)));
+                       case GT:
+                               return new 
GreaterThanEvaluator(buildReferenceEvaluator(tree.getChild(0)), 
buildReferenceEvaluator(tree.getChild(1)));
+                       case LT:
+                               return new 
LessThanEvaluator(buildReferenceEvaluator(tree.getChild(0)), 
buildReferenceEvaluator(tree.getChild(1)));
+                       case GE:
+                               return new 
GreaterThanOrEqualEvaluator(buildReferenceEvaluator(tree.getChild(0)), 
buildReferenceEvaluator(tree.getChild(1)));
+                       case LE:
+                               return new 
LessThanOrEqualEvaluator(buildReferenceEvaluator(tree.getChild(0)), 
buildReferenceEvaluator(tree.getChild(1)));
+                       case NOT:
+                               return new 
NotEvaluator(buildBooleanEvaluator(tree.getChild(0)));
+                       case AND:
+                               return new 
AndEvaluator(buildBooleanEvaluator(tree.getChild(0)), 
buildBooleanEvaluator(tree.getChild(1)));
+                       case OR:
+                               return new 
OrEvaluator(buildBooleanEvaluator(tree.getChild(0)), 
buildBooleanEvaluator(tree.getChild(1)));
+                       case IS_NULL:
+                               return new 
IsNullEvaluator(buildReferenceEvaluator(tree.getChild(0)));
+                       case NOT_NULL:
+                               return new 
NotNullEvaluator(buildReferenceEvaluator(tree.getChild(0)));
+                       default:
+                               throw new HL7QueryParsingException("Cannot 
build boolean evaluator for '" + tree.getText() + "'");
+               }
+       }
+       
+       
+       Tree getTree() {
+               return tree;
+       }
+       
+       public String getQuery() {
+               return query;
+       }
+       
+       @Override
+       public String toString() {
+               return "HL7Query[" + query + "]";
+       }
+       
+       public static HL7Query compile(final String query) {
+               try {
+            final CommonTokenStream lexerTokenStream = 
createTokenStream(query);
+            final HL7QueryParser parser = new HL7QueryParser(lexerTokenStream);
+            final Tree tree = (Tree) parser.query().getTree();
+
+            return new HL7Query(tree, query);
+        } catch (final HL7QueryParsingException e) {
+            throw e;
+        } catch (final Exception e) {
+            throw new HL7QueryParsingException(e);
+        }
+       }
+       
+       private static CommonTokenStream createTokenStream(final String 
expression) throws HL7QueryParsingException {
+        final CharStream input = new ANTLRStringStream(expression);
+        final HL7QueryLexer lexer = new HL7QueryLexer(input);
+        return new CommonTokenStream(lexer);
+    }
+       
+       public List<Class<?>> getReturnTypes() {
+               final List<Class<?>> returnTypes = new ArrayList<>();
+               
+               for ( final Selection selection : selections ) {
+                       returnTypes.add( selection.getEvaluator().getType() );
+               }
+               
+               return returnTypes;
+       }
+       
+       @SuppressWarnings("unchecked")
+       public QueryResult evaluate(final HL7Message message) {
+               
+               int totalIterations = 1;
+               final LinkedHashMap<String, List<Object>> possibleValueMap = 
new LinkedHashMap<>();
+               for ( final Declaration declaration : declarations ) {
+                       final Object value = 
declaration.getDeclaredValue(message);
+                       if ( value == null && declaration.isRequired() ) {
+                               return new MissedResult(selections);
+                       }
+
+                       final List<Object> possibleValues;
+                       if ( value instanceof List ) {
+                               possibleValues = (List<Object>) value;
+                       } else if ( value instanceof Collection ) {
+                               possibleValues = new 
ArrayList<Object>((Collection<Object>) value);
+                       } else {
+                               possibleValues = new ArrayList<>(1);
+                               possibleValues.add(value);
+                       }
+                       
+                       if ( possibleValues.isEmpty() ) {
+                               return new MissedResult(selections);
+                       }
+                       
+                       possibleValueMap.put(declaration.getAlias(), 
possibleValues);
+                       totalIterations *= possibleValues.size();
+               }
+
+               final Set<Map<String, Object>> resultSet = new HashSet<>();
+               for (int i=0; i < totalIterations; i++) {
+                       final Map<String, Object> aliasValues = 
assignAliases(possibleValueMap, i);
+
+                       aliasValues.put(Evaluator.MESSAGE_KEY, message);
+                       if (whereEvaluator == null || 
Boolean.TRUE.equals(whereEvaluator.evaluate(aliasValues))) {
+                               final Map<String, Object> resultMap = new 
HashMap<>();
+
+                               for ( final Selection selection : selections ) {
+                                       final Object value = 
selection.getEvaluator().evaluate(aliasValues);
+                                       resultMap.put(selection.getName(), 
value);
+                               }
+                               
+                               resultSet.add(resultMap);
+                       }
+               }
+               
+//             for ( final Declaration declaration : declarations ) {
+//                     final Object value = 
declaration.getDeclaredValue(message);
+//                     if ( value == null && declaration.isRequired() ) {
+//                             return new MissedResult(selections);
+//                     }
+//                     objectMap.put(declaration.getAlias(), value);
+//             }
+//             
+//             if (whereEvaluator == null || 
Boolean.TRUE.equals(whereEvaluator.evaluate(objectMap))) {
+//                     for ( final Selection selection : selections ) {
+//                             final Object value = 
selection.getEvaluator().evaluate(objectMap);
+//                             resultMap.put(selection.getName(), value);
+//                     }
+//             } else {
+//                     return new MissedResult(selections);
+//             }
+               
+               return new StandardQueryResult(selections, resultSet);
+       }
+       
+       
+       // assigns one of the possible values to each alias, based on which 
iteration this is.
+       // require LinkedHashMap just to be very clear and explicit that the 
order of the Map MUST be guaranteed
+       // between multiple invocations of this method.
+       // package protected for testing visibility
+//     static Map<String, Object> assignAliases(final LinkedHashMap<String, 
List<Object>> possibleValues, final int iteration) {
+//             final Map<String, Object> aliasMap = new HashMap<>();
+//             
+//             int aliasIndex = possibleValues.size() - 1;
+//             for ( final Map.Entry<String, List<Object>> entry : 
possibleValues.entrySet() ) {
+//                     final String alias = entry.getKey();
+//                     final List<Object> validValues = entry.getValue();
+//
+//                     final int validValueIndex;
+//                     if (aliasIndex > 0) {
+//                             validValueIndex = iteration / aliasIndex;
+//                     } else {
+//                             validValueIndex = iteration;
+//                     }
+//                     
+//                     final Object obj = validValues.get(validValueIndex % 
validValues.size());
+//                     aliasMap.put(alias, obj);
+//                     
+//                     aliasIndex--;
+//             }
+//             
+//             return aliasMap;
+//     }
+//     
+       
+       static Map<String, Object> assignAliases(final LinkedHashMap<String, 
List<Object>> possibleValues, final int iteration) {
+               final Map<String, Object> aliasMap = new HashMap<>();
+               
+               int divisor = 1;
+               for ( final Map.Entry<String, List<Object>> entry : 
possibleValues.entrySet() ) {
+                       final String alias = entry.getKey();
+                       final List<Object> validValues = entry.getValue();
+
+                       final int idx = (iteration / divisor) % 
validValues.size();
+                       final Object obj = validValues.get(idx);
+                       aliasMap.put(alias, obj);
+                       
+                       divisor *= validValues.size();
+               }
+               
+               return aliasMap;
+       }
+       
+       public String toTreeString() {
+               final StringBuilder sb = new StringBuilder();
+               toTreeString(tree, sb, 0);
+               return sb.toString();
+       }
+       
+       private void toTreeString(final Tree tree, final StringBuilder sb, 
final int indentLevel) {
+               final String nodeName = tree.getText();
+               for (int i=0; i < indentLevel; i++) {
+                       sb.append(" ");
+               }
+               sb.append(nodeName);
+               sb.append("\n");
+               
+               for (int i=0; i < tree.getChildCount(); i++) {
+                       final Tree child = tree.getChild(i);
+                       toTreeString(child, sb, indentLevel + 2);
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/QueryResult.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/QueryResult.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/QueryResult.java
new file mode 100644
index 0000000..b198bc7
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/QueryResult.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.query;
+
+import java.util.List;
+
+public interface QueryResult {
+       boolean isMatch();
+       
+       List<String> getLabels();
+       
+       int getHitCount();
+       
+       ResultHit nextHit();
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/ResultHit.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/ResultHit.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/ResultHit.java
new file mode 100644
index 0000000..ee97e5d
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/ResultHit.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.query;
+
+import java.util.Map;
+
+public interface ResultHit {
+       Object getValue(String label);
+       
+       Map<String, Object> getSelectedValues();
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/Selection.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/Selection.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/Selection.java
new file mode 100644
index 0000000..36a181f
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/Selection.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.query;
+
+import org.apache.nifi.hl7.query.evaluator.Evaluator;
+
+public class Selection {
+       private final Evaluator<?> evaluator;
+       private final String name;
+       
+       public Selection(final Evaluator<?> evaluator, final String name) {
+               this.evaluator = evaluator;
+               this.name = name;
+       }
+       
+       public String getName() {
+               return name;
+       }
+       
+       public Evaluator<?> getEvaluator() {
+               return evaluator;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/BooleanEvaluator.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/BooleanEvaluator.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/BooleanEvaluator.java
new file mode 100644
index 0000000..fdd807e
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/BooleanEvaluator.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.query.evaluator;
+
+public abstract class BooleanEvaluator implements Evaluator<Boolean> {
+
+       public Class<? extends Boolean> getType() {
+               return Boolean.class;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/Evaluator.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/Evaluator.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/Evaluator.java
new file mode 100644
index 0000000..d86c30e
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/Evaluator.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.query.evaluator;
+
+import java.util.Map;
+
+public interface Evaluator<T> {
+       public static final String MESSAGE_KEY = "message";
+       
+       T evaluate(Map<String, Object> objectMap);
+       
+       Class<? extends T> getType();
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/IntegerEvaluator.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/IntegerEvaluator.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/IntegerEvaluator.java
new file mode 100644
index 0000000..6afa9ed
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/IntegerEvaluator.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.query.evaluator;
+
+
+public abstract class IntegerEvaluator implements Evaluator<Integer> {
+
+       public Class<? extends Integer> getType() {
+               return Integer.class;
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/StringEvaluator.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/StringEvaluator.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/StringEvaluator.java
new file mode 100644
index 0000000..5f73649
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/StringEvaluator.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.query.evaluator;
+
+public abstract class StringEvaluator implements Evaluator<String> {
+
+       public Class<? extends String> getType() {
+               return String.class;
+       }
+       
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/AbstractComparisonEvaluator.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/AbstractComparisonEvaluator.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/AbstractComparisonEvaluator.java
new file mode 100644
index 0000000..a7fa1b7
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/AbstractComparisonEvaluator.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.query.evaluator.comparison;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.nifi.hl7.model.HL7Field;
+import org.apache.nifi.hl7.query.evaluator.BooleanEvaluator;
+import org.apache.nifi.hl7.query.evaluator.Evaluator;
+
+public abstract class AbstractComparisonEvaluator extends BooleanEvaluator {
+       private final Evaluator<?> lhs;
+       private final Evaluator<?> rhs;
+       
+       public AbstractComparisonEvaluator(final Evaluator<?> lhs, final 
Evaluator<?> rhs) {
+               this.lhs = lhs;
+               this.rhs = rhs;
+       }
+       
+       public final Boolean evaluate(final Map<String, Object> objectMap) {
+               final Object lhsValue = lhs.evaluate(objectMap);
+               if ( lhsValue == null ) {
+                       return false;
+               }
+               
+               final Object rhsValue = rhs.evaluate(objectMap);
+               if ( rhsValue == null ) {
+                       return false;
+               }
+               
+               return compareRaw(lhsValue, rhsValue);
+       }
+       
+       
+       private Boolean compareRaw(Object lhsValue, Object rhsValue) {
+               if ( lhsValue == null || rhsValue == null ) {
+                       return false;
+               }
+
+               if ( lhsValue instanceof HL7Field ) {
+                       lhsValue = ((HL7Field) lhsValue).getValue();
+               }
+               
+               if ( rhsValue instanceof HL7Field ) {
+                       rhsValue = ((HL7Field) rhsValue).getValue();
+               }
+
+               if ( lhsValue == null || rhsValue == null ) {
+                       return false;
+               }
+               
+               // both are collections, and compare(lhsValue, rhsValue) is 
false.
+               // this would be the case, for instance, if we compared field 1 
of one segment to 
+               // a field in another segment, and both fields had components.
+               if ( lhsValue instanceof Collection && rhsValue instanceof 
Collection ) {
+                       return false;
+               }
+               
+               // if one side is a collection but the other is not, check if 
any element in that
+               // collection compares to the other element in a way that 
satisfies the condition.
+               // this would happen, for instance, if we check Segment1.Field5 
= 'X' and field 5 repeats
+               // with a value "A~B~C~X~Y~Z"; in this case we do want to 
consider Field 5 = X as true.
+               if ( lhsValue instanceof Collection ) {
+                       for ( final Object lhsObject : (Collection<?>) lhsValue 
) {
+                               if ( compareRaw(lhsObject, rhsValue) ) {
+                                       return true;
+                               }
+                       }
+                       
+                       return false;
+               }
+               
+               if ( rhsValue instanceof Collection ) {
+                       for ( final Object rhsObject : (Collection<?>) rhsValue 
) {
+                               if ( compareRaw(rhsObject, lhsValue) ) {
+                                       return true;
+                               }
+                       }
+                       
+                       return false;
+               }
+               
+               if ( lhsValue != null && rhsValue != null && compare(lhsValue, 
rhsValue) ) {
+                       return true;
+               }
+               
+               return false;
+       }
+       
+       protected abstract boolean compare(Object lhs, Object rhs);
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/AbstractNumericComparison.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/AbstractNumericComparison.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/AbstractNumericComparison.java
new file mode 100644
index 0000000..2529c49
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/AbstractNumericComparison.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.query.evaluator.comparison;
+
+import java.util.regex.Pattern;
+
+import org.apache.nifi.hl7.query.evaluator.Evaluator;
+
+public abstract class AbstractNumericComparison extends 
AbstractComparisonEvaluator {
+       private static final Pattern NUMERIC_PATTERN = 
Pattern.compile("\\d+(\\.\\d+)?");
+       
+       public AbstractNumericComparison(final Evaluator<?> lhs, final 
Evaluator<?> rhs) {
+               super(lhs, rhs);
+       }
+       
+       @Override
+       protected final boolean compare(final Object lhs, final Object rhs) {
+               final Double lhsDouble = toDouble(lhs);
+               if ( lhsDouble == null ) {
+                       return false;
+               }
+               
+               final Double rhsDouble = toDouble(rhs);
+               if ( rhsDouble == null ) {
+                       return false;
+               }
+               
+               return compareNumbers(lhsDouble, rhsDouble);
+       }
+
+       private Double toDouble(final Object value) {
+               if ( value == null ) {
+                       return null;
+               }
+               
+               if ( value instanceof Double ) {
+                       return (Double) value;
+               }
+               if ( value instanceof Number ) {
+                       return ((Number) value).doubleValue();
+               }
+               
+               if ( value instanceof String ) {
+                       if ( NUMERIC_PATTERN.matcher((String) value).matches() 
) {
+                               return Double.parseDouble((String) value);
+                       }
+               }
+               
+               return null;
+       }
+       
+       protected abstract boolean compareNumbers(final Double lhs, final 
Double rhs);
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/EqualsEvaluator.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/EqualsEvaluator.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/EqualsEvaluator.java
new file mode 100644
index 0000000..7ee2f87
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/EqualsEvaluator.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.query.evaluator.comparison;
+
+import org.apache.nifi.hl7.query.evaluator.Evaluator;
+
+public class EqualsEvaluator extends AbstractComparisonEvaluator {
+
+       public EqualsEvaluator(final Evaluator<?> lhs, final Evaluator<?> rhs) {
+               super(lhs, rhs);
+       }
+       
+       @Override
+       protected boolean compare(final Object lhs, final Object rhs) {
+               return lhs != null && rhs != null && ((lhs == rhs) || 
(lhs.equals(rhs)) || lhs.toString().equals(rhs.toString()));
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/GreaterThanEvaluator.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/GreaterThanEvaluator.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/GreaterThanEvaluator.java
new file mode 100644
index 0000000..bf8596e
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/GreaterThanEvaluator.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.query.evaluator.comparison;
+
+import org.apache.nifi.hl7.query.evaluator.Evaluator;
+
+
+public class GreaterThanEvaluator extends AbstractNumericComparison {
+
+       public GreaterThanEvaluator(final Evaluator<?> lhs, final Evaluator<?> 
rhs) {
+               super(lhs, rhs);
+       }
+
+       @Override
+       protected boolean compareNumbers(final Double lhs, final Double rhs) {
+               return lhs > rhs;
+       }
+
+       
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/GreaterThanOrEqualEvaluator.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/GreaterThanOrEqualEvaluator.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/GreaterThanOrEqualEvaluator.java
new file mode 100644
index 0000000..69115a3
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/GreaterThanOrEqualEvaluator.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.query.evaluator.comparison;
+
+import org.apache.nifi.hl7.query.evaluator.Evaluator;
+
+
+public class GreaterThanOrEqualEvaluator extends AbstractNumericComparison {
+
+       public GreaterThanOrEqualEvaluator(final Evaluator<?> lhs, final 
Evaluator<?> rhs) {
+               super(lhs, rhs);
+       }
+
+       @Override
+       protected boolean compareNumbers(final Double lhs, final Double rhs) {
+               return lhs >= rhs;
+       }
+
+       
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/IsNullEvaluator.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/IsNullEvaluator.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/IsNullEvaluator.java
new file mode 100644
index 0000000..69d481e
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/IsNullEvaluator.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.query.evaluator.comparison;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.nifi.hl7.model.HL7Component;
+import org.apache.nifi.hl7.query.evaluator.BooleanEvaluator;
+import org.apache.nifi.hl7.query.evaluator.Evaluator;
+
+public class IsNullEvaluator extends BooleanEvaluator {
+       private final Evaluator<?> subjectEvaluator;
+       
+       public IsNullEvaluator(final Evaluator<?> subjectEvaluator) {
+               this.subjectEvaluator = subjectEvaluator;
+       }
+       
+       @Override
+       public Boolean evaluate(final Map<String, Object> objectMap) {
+               Object subjectValue = subjectEvaluator.evaluate(objectMap);
+               if ( subjectValue == null ) {
+                       return true;
+               }
+               
+               return isNull(subjectValue);
+       }
+
+       private boolean isNull(Object subjectValue) {
+               if ( subjectValue == null ) {
+                       return true;
+               }
+               
+               if ( subjectValue instanceof HL7Component ) {
+                       subjectValue = ((HL7Component) subjectValue).getValue();
+               }
+               
+               if ( subjectValue instanceof Collection ) {
+                       final Collection<?> collection = (Collection<?>) 
subjectValue;
+                       if ( collection.isEmpty() ) {
+                               return true;
+                       }
+                       
+                       for ( final Object obj : collection ) {
+                               if ( !isNull(obj) ) {
+                                       return false;
+                               }
+                       }
+                       
+                       return true;
+               }
+               
+               return subjectValue == null;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/LessThanEvaluator.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/LessThanEvaluator.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/LessThanEvaluator.java
new file mode 100644
index 0000000..891d5e4
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/LessThanEvaluator.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.query.evaluator.comparison;
+
+import org.apache.nifi.hl7.query.evaluator.Evaluator;
+
+public class LessThanEvaluator extends AbstractNumericComparison {
+       public LessThanEvaluator(final Evaluator<?> lhs, final Evaluator<?> 
rhs) {
+               super(lhs, rhs);
+       }
+
+       @Override
+       protected boolean compareNumbers(final Double lhs, final Double rhs) {
+               return lhs < rhs;
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/45416dc6/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/LessThanOrEqualEvaluator.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/LessThanOrEqualEvaluator.java
 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/LessThanOrEqualEvaluator.java
new file mode 100644
index 0000000..c6fb097
--- /dev/null
+++ 
b/nifi/nifi-commons/nifi-hl7-query-language/src/main/java/org/apache/nifi/hl7/query/evaluator/comparison/LessThanOrEqualEvaluator.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.hl7.query.evaluator.comparison;
+
+import org.apache.nifi.hl7.query.evaluator.Evaluator;
+
+public class LessThanOrEqualEvaluator extends AbstractNumericComparison {
+       public LessThanOrEqualEvaluator(final Evaluator<?> lhs, final 
Evaluator<?> rhs) {
+               super(lhs, rhs);
+       }
+
+       @Override
+       protected boolean compareNumbers(final Double lhs, final Double rhs) {
+               return lhs <= rhs;
+       }
+
+}

Reply via email to