You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nlpcraft.apache.org by ar...@apache.org on 2021/03/09 17:43:48 UTC

[incubator-nlpcraft] branch NLPCRAFT-206 updated (3f77b6f -> 7ed48e1)

This is an automated email from the ASF dual-hosted git repository.

aradzinski pushed a change to branch NLPCRAFT-206
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git.


    from 3f77b6f  WIP.
     new 67255ef  WIP.
     new 7ed48e1  WIP.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../intent/compiler}/antlr4/NCIntentDsl.interp     |   0
 .../intent/compiler}/antlr4/NCIntentDsl.tokens     |   0
 .../compiler}/antlr4/NCIntentDslBaseListener.java  |   4 +-
 .../compiler/antlr4/NCIntentDslBaseVisitor.java    | 308 ++++++++++++++
 .../compiler}/antlr4/NCIntentDslLexer.interp       |   0
 .../intent/compiler}/antlr4/NCIntentDslLexer.java  |   4 +-
 .../compiler}/antlr4/NCIntentDslLexer.tokens       |   0
 .../compiler}/antlr4/NCIntentDslListener.java      |   4 +-
 .../intent/compiler}/antlr4/NCIntentDslParser.java | 214 +++++++++-
 .../intent/compiler/antlr4/NCIntentDslVisitor.java | 274 ++++++++++++
 .../scala/org/apache/nlpcraft/common/package.scala |   3 -
 .../nlpcraft/model/impl/json/NCModelJson.java      |   8 +-
 .../NCIntentDslBaselCompiler.scala                 | 315 +++++---------
 .../{impl => compiler}/NCIntentDslCompiler.scala   | 302 ++++++++-----
 .../NCIntentDslFragmentCache.scala                 |  48 +--
 .../{impl => compiler}/antlr4/NCIntentDsl.g4       |   0
 .../{impl => compiler}/antlr4/NCIntentDsl.interp   |   0
 .../{impl => compiler}/antlr4/NCIntentDsl.tokens   |   0
 .../antlr4/NCIntentDslBaseListener.java            |   2 +-
 .../antlr4/NCIntentDslLexer.interp                 |   0
 .../antlr4/NCIntentDslLexer.java                   |   5 +-
 .../antlr4/NCIntentDslLexer.tokens                 |   0
 .../antlr4/NCIntentDslListener.java                |   2 +-
 .../antlr4/NCIntentDslParser.java                  |   5 +-
 .../intent/{impl => solver}/NCIntentSolver.scala   |   7 +-
 .../{impl => solver}/NCIntentSolverEngine.scala    | 189 ++++----
 .../{impl => solver}/NCIntentSolverInput.scala     |   2 +-
 .../{impl => solver}/NCIntentSolverResult.scala    |   4 +-
 .../{impl => solver}/NCIntentSolverVariant.scala   |  35 +-
 .../model/intent/utils/NCDslTokenChecker.scala     |  46 --
 .../model/intent/utils/NCDslTokenPredicate.java    | 473 ---------------------
 .../model/intent/utils/NCDslTokenQualifier.scala   |  62 ---
 .../apache/nlpcraft/probe/mgrs/NCProbeModel.scala  |   2 +-
 .../probe/mgrs/deploy/NCDeployManager.scala        |  10 +-
 .../mgrs/dialogflow/NCDialogFlowManager.scala      |   2 +-
 .../probe/mgrs/nlp/NCProbeEnrichmentManager.scala  |   2 +-
 .../dsl/compiler/NCIntentDslCompilerSpec.scala     |   9 +-
 37 files changed, 1263 insertions(+), 1078 deletions(-)
 copy nlpcraft/{src/main/scala/org/apache/nlpcraft/model/intent/impl => gen/org/apache/nlpcraft/model/intent/compiler}/antlr4/NCIntentDsl.interp (100%)
 copy nlpcraft/{src/main/scala/org/apache/nlpcraft/model/intent/impl => gen/org/apache/nlpcraft/model/intent/compiler}/antlr4/NCIntentDsl.tokens (100%)
 copy nlpcraft/{src/main/scala/org/apache/nlpcraft/model/intent/impl => gen/org/apache/nlpcraft/model/intent/compiler}/antlr4/NCIntentDslBaseListener.java (99%)
 create mode 100644 nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslBaseVisitor.java
 copy nlpcraft/{src/main/scala/org/apache/nlpcraft/model/intent/impl => gen/org/apache/nlpcraft/model/intent/compiler}/antlr4/NCIntentDslLexer.interp (100%)
 copy nlpcraft/{src/main/scala/org/apache/nlpcraft/model/intent/impl => gen/org/apache/nlpcraft/model/intent/compiler}/antlr4/NCIntentDslLexer.java (99%)
 copy nlpcraft/{src/main/scala/org/apache/nlpcraft/model/intent/impl => gen/org/apache/nlpcraft/model/intent/compiler}/antlr4/NCIntentDslLexer.tokens (100%)
 copy nlpcraft/{src/main/scala/org/apache/nlpcraft/model/intent/impl => gen/org/apache/nlpcraft/model/intent/compiler}/antlr4/NCIntentDslListener.java (99%)
 copy nlpcraft/{src/main/scala/org/apache/nlpcraft/model/intent/impl => gen/org/apache/nlpcraft/model/intent/compiler}/antlr4/NCIntentDslParser.java (89%)
 create mode 100644 nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslVisitor.java
 rename nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/{impl => compiler}/NCIntentDslBaselCompiler.scala (66%)
 rename nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/{impl => compiler}/NCIntentDslCompiler.scala (71%)
 rename nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/{impl => compiler}/NCIntentDslFragmentCache.scala (81%)
 rename nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/{impl => compiler}/antlr4/NCIntentDsl.g4 (100%)
 rename nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/{impl => compiler}/antlr4/NCIntentDsl.interp (100%)
 rename nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/{impl => compiler}/antlr4/NCIntentDsl.tokens (100%)
 rename nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/{impl => compiler}/antlr4/NCIntentDslBaseListener.java (99%)
 rename nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/{impl => compiler}/antlr4/NCIntentDslLexer.interp (100%)
 rename nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/{impl => compiler}/antlr4/NCIntentDslLexer.java (99%)
 rename nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/{impl => compiler}/antlr4/NCIntentDslLexer.tokens (100%)
 rename nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/{impl => compiler}/antlr4/NCIntentDslListener.java (99%)
 rename nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/{impl => compiler}/antlr4/NCIntentDslParser.java (99%)
 rename nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/{impl => solver}/NCIntentSolver.scala (97%)
 rename nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/{impl => solver}/NCIntentSolverEngine.scala (88%)
 rename nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/{impl => solver}/NCIntentSolverInput.scala (95%)
 rename nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/{impl => solver}/NCIntentSolverResult.scala (90%)
 rename nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/{impl => solver}/NCIntentSolverVariant.scala (66%)
 delete mode 100644 nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/utils/NCDslTokenChecker.scala
 delete mode 100644 nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/utils/NCDslTokenPredicate.java
 delete mode 100644 nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/utils/NCDslTokenQualifier.scala


[incubator-nlpcraft] 02/02: WIP.

Posted by ar...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aradzinski pushed a commit to branch NLPCRAFT-206
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git

commit 7ed48e115f6d46bdf8a961355441b84dfdf1bb5e
Author: Aaron Radzinski <ar...@apache.org>
AuthorDate: Tue Mar 9 09:43:37 2021 -0800

    WIP.
---
 .../intent/compiler}/antlr4/NCIntentDsl.interp     |   0
 .../intent/compiler}/antlr4/NCIntentDsl.tokens     |   0
 .../compiler}/antlr4/NCIntentDslBaseListener.java  |   4 +-
 .../compiler/antlr4/NCIntentDslBaseVisitor.java    | 308 ++++++++++++++
 .../compiler}/antlr4/NCIntentDslLexer.interp       |   0
 .../intent/compiler}/antlr4/NCIntentDslLexer.java  |   4 +-
 .../compiler}/antlr4/NCIntentDslLexer.tokens       |   0
 .../compiler}/antlr4/NCIntentDslListener.java      |   4 +-
 .../intent/compiler}/antlr4/NCIntentDslParser.java | 214 +++++++++-
 .../intent/compiler/antlr4/NCIntentDslVisitor.java | 274 ++++++++++++
 .../scala/org/apache/nlpcraft/common/package.scala |   3 -
 .../nlpcraft/model/impl/json/NCModelJson.java      |   8 +-
 .../NCIntentDslBaselCompiler.scala                 | 182 ++++----
 .../{impl => compiler}/NCIntentDslCompiler.scala   |  88 ++--
 .../NCIntentDslFragmentCache.scala                 |  48 +--
 .../{impl => compiler}/antlr4/NCIntentDsl.g4       |   0
 .../{impl => compiler}/antlr4/NCIntentDsl.interp   |   0
 .../{impl => compiler}/antlr4/NCIntentDsl.tokens   |   0
 .../antlr4/NCIntentDslBaseListener.java            |   2 +-
 .../antlr4/NCIntentDslLexer.interp                 |   0
 .../antlr4/NCIntentDslLexer.java                   |   5 +-
 .../antlr4/NCIntentDslLexer.tokens                 |   0
 .../antlr4/NCIntentDslListener.java                |   2 +-
 .../antlr4/NCIntentDslParser.java                  |   5 +-
 .../intent/{impl => solver}/NCIntentSolver.scala   |   7 +-
 .../{impl => solver}/NCIntentSolverEngine.scala    | 189 ++++----
 .../{impl => solver}/NCIntentSolverInput.scala     |   2 +-
 .../{impl => solver}/NCIntentSolverResult.scala    |   4 +-
 .../{impl => solver}/NCIntentSolverVariant.scala   |  35 +-
 .../model/intent/utils/NCDslTokenChecker.scala     |  46 --
 .../model/intent/utils/NCDslTokenPredicate.java    | 473 ---------------------
 .../model/intent/utils/NCDslTokenQualifier.scala   |  62 ---
 .../apache/nlpcraft/probe/mgrs/NCProbeModel.scala  |   2 +-
 .../probe/mgrs/deploy/NCDeployManager.scala        |   4 +-
 .../mgrs/dialogflow/NCDialogFlowManager.scala      |   2 +-
 .../probe/mgrs/nlp/NCProbeEnrichmentManager.scala  |   2 +-
 .../dsl/compiler/NCIntentDslCompilerSpec.scala     |   3 +-
 37 files changed, 1078 insertions(+), 904 deletions(-)

diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDsl.interp b/nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDsl.interp
similarity index 100%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDsl.interp
copy to nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDsl.interp
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDsl.tokens b/nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDsl.tokens
similarity index 100%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDsl.tokens
copy to nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDsl.tokens
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslBaseListener.java b/nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslBaseListener.java
similarity index 99%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslBaseListener.java
copy to nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslBaseListener.java
index 3c6c2cf..93503f4 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslBaseListener.java
+++ b/nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslBaseListener.java
@@ -1,5 +1,5 @@
-// Generated from C:/Users/Nikita Ivanov/Documents/GitHub/incubator-nlpcraft/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4\NCIntentDsl.g4 by ANTLR 4.9.1
-package org.apache.nlpcraft.model.intent.impl.antlr4;
+// Generated from C:/Users/Nikita Ivanov/Documents/GitHub/incubator-nlpcraft/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4\NCIntentDsl.g4 by ANTLR 4.9.1
+package org.apache.nlpcraft.model.intent.compiler.antlr4;
 
 import org.antlr.v4.runtime.ParserRuleContext;
 import org.antlr.v4.runtime.tree.ErrorNode;
diff --git a/nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslBaseVisitor.java b/nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslBaseVisitor.java
new file mode 100644
index 0000000..6944592
--- /dev/null
+++ b/nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslBaseVisitor.java
@@ -0,0 +1,308 @@
+// Generated from C:/Users/Nikita Ivanov/Documents/GitHub/incubator-nlpcraft/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4\NCIntentDsl.g4 by ANTLR 4.9.1
+package org.apache.nlpcraft.model.intent.compiler.antlr4;
+import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
+
+/**
+ * This class provides an empty implementation of {@link NCIntentDslVisitor},
+ * which can be extended to create a visitor which only needs to handle a subset
+ * of the available methods.
+ *
+ * @param <T> The return type of the visit operation. Use {@link Void} for
+ * operations with no return type.
+ */
+public class NCIntentDslBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements NCIntentDslVisitor<T> {
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitDsl(NCIntentDslParser.DslContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitSynonym(NCIntentDslParser.SynonymContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitAlias(NCIntentDslParser.AliasContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitDslItems(NCIntentDslParser.DslItemsContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitDslItem(NCIntentDslParser.DslItemContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitFrag(NCIntentDslParser.FragContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitFragId(NCIntentDslParser.FragIdContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitFragRef(NCIntentDslParser.FragRefContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitFragMeta(NCIntentDslParser.FragMetaContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitIntent(NCIntentDslParser.IntentContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitIntentId(NCIntentDslParser.IntentIdContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitOrderedDecl(NCIntentDslParser.OrderedDeclContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitMtdDecl(NCIntentDslParser.MtdDeclContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitFlowDecl(NCIntentDslParser.FlowDeclContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitMetaDecl(NCIntentDslParser.MetaDeclContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitJsonObj(NCIntentDslParser.JsonObjContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitJsonPair(NCIntentDslParser.JsonPairContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitJsonVal(NCIntentDslParser.JsonValContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitJsonArr(NCIntentDslParser.JsonArrContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitTerms(NCIntentDslParser.TermsContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitTermItem(NCIntentDslParser.TermItemContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitTermEq(NCIntentDslParser.TermEqContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitTerm(NCIntentDslParser.TermContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitMtdRef(NCIntentDslParser.MtdRefContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitJavaFqn(NCIntentDslParser.JavaFqnContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitTermId(NCIntentDslParser.TermIdContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitParExpr(NCIntentDslParser.ParExprContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitEqExpr(NCIntentDslParser.EqExprContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitUnaryExpr(NCIntentDslParser.UnaryExprContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitCompExpr(NCIntentDslParser.CompExprContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitAtomExpr(NCIntentDslParser.AtomExprContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitCallExpr(NCIntentDslParser.CallExprContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitMultExpr(NCIntentDslParser.MultExprContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitPlusExpr(NCIntentDslParser.PlusExprContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitLogExpr(NCIntentDslParser.LogExprContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitParamList(NCIntentDslParser.ParamListContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitAtom(NCIntentDslParser.AtomContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitQstring(NCIntentDslParser.QstringContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitMinMax(NCIntentDslParser.MinMaxContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitMinMaxShortcut(NCIntentDslParser.MinMaxShortcutContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitMinMaxRange(NCIntentDslParser.MinMaxRangeContext ctx) { return visitChildren(ctx); }
+	/**
+	 * {@inheritDoc}
+	 *
+	 * <p>The default implementation returns the result of calling
+	 * {@link #visitChildren} on {@code ctx}.</p>
+	 */
+	@Override public T visitId(NCIntentDslParser.IdContext ctx) { return visitChildren(ctx); }
+}
\ No newline at end of file
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.interp b/nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslLexer.interp
similarity index 100%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.interp
copy to nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslLexer.interp
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.java b/nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslLexer.java
similarity index 99%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.java
copy to nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslLexer.java
index aeb35e2..eb4a726 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.java
+++ b/nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslLexer.java
@@ -1,5 +1,5 @@
-// Generated from C:/Users/Nikita Ivanov/Documents/GitHub/incubator-nlpcraft/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4\NCIntentDsl.g4 by ANTLR 4.9.1
-package org.apache.nlpcraft.model.intent.impl.antlr4;
+// Generated from C:/Users/Nikita Ivanov/Documents/GitHub/incubator-nlpcraft/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4\NCIntentDsl.g4 by ANTLR 4.9.1
+package org.apache.nlpcraft.model.intent.compiler.antlr4;
 import org.antlr.v4.runtime.Lexer;
 import org.antlr.v4.runtime.CharStream;
 import org.antlr.v4.runtime.Token;
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.tokens b/nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslLexer.tokens
similarity index 100%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.tokens
copy to nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslLexer.tokens
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslListener.java b/nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslListener.java
similarity index 99%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslListener.java
copy to nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslListener.java
index 904069b..e220659 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslListener.java
+++ b/nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslListener.java
@@ -1,5 +1,5 @@
-// Generated from C:/Users/Nikita Ivanov/Documents/GitHub/incubator-nlpcraft/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4\NCIntentDsl.g4 by ANTLR 4.9.1
-package org.apache.nlpcraft.model.intent.impl.antlr4;
+// Generated from C:/Users/Nikita Ivanov/Documents/GitHub/incubator-nlpcraft/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4\NCIntentDsl.g4 by ANTLR 4.9.1
+package org.apache.nlpcraft.model.intent.compiler.antlr4;
 import org.antlr.v4.runtime.tree.ParseTreeListener;
 
 /**
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslParser.java b/nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslParser.java
similarity index 89%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslParser.java
copy to nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslParser.java
index 976d4c3..e77bf57 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslParser.java
+++ b/nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslParser.java
@@ -1,5 +1,5 @@
-// Generated from C:/Users/Nikita Ivanov/Documents/GitHub/incubator-nlpcraft/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4\NCIntentDsl.g4 by ANTLR 4.9.1
-package org.apache.nlpcraft.model.intent.impl.antlr4;
+// Generated from C:/Users/Nikita Ivanov/Documents/GitHub/incubator-nlpcraft/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4\NCIntentDsl.g4 by ANTLR 4.9.1
+package org.apache.nlpcraft.model.intent.compiler.antlr4;
 import org.antlr.v4.runtime.atn.*;
 import org.antlr.v4.runtime.dfa.DFA;
 import org.antlr.v4.runtime.*;
@@ -132,6 +132,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitDsl(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitDsl(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final DslContext dsl() throws RecognitionException {
@@ -179,6 +184,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitSynonym(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitSynonym(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final SynonymContext synonym() throws RecognitionException {
@@ -237,6 +247,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitAlias(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitAlias(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final AliasContext alias() throws RecognitionException {
@@ -283,6 +298,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitDslItems(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitDslItems(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final DslItemsContext dslItems() throws RecognitionException {
@@ -359,6 +379,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitDslItem(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitDslItem(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final DslItemContext dslItem() throws RecognitionException {
@@ -416,6 +441,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitFrag(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitFrag(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final FragContext frag() throws RecognitionException {
@@ -459,6 +489,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitFragId(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitFragId(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final FragIdContext fragId() throws RecognitionException {
@@ -508,6 +543,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitFragRef(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitFragRef(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final FragRefContext fragRef() throws RecognitionException {
@@ -565,6 +605,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitFragMeta(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitFragMeta(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final FragMetaContext fragMeta() throws RecognitionException {
@@ -618,6 +663,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitIntent(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitIntent(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final IntentContext intent() throws RecognitionException {
@@ -691,6 +741,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitIntentId(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitIntentId(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final IntentIdContext intentId() throws RecognitionException {
@@ -733,6 +788,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitOrderedDecl(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitOrderedDecl(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final OrderedDeclContext orderedDecl() throws RecognitionException {
@@ -780,6 +840,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitMtdDecl(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitMtdDecl(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final MtdDeclContext mtdDecl() throws RecognitionException {
@@ -827,6 +892,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitFlowDecl(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitFlowDecl(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final FlowDeclContext flowDecl() throws RecognitionException {
@@ -888,6 +958,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitMetaDecl(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitMetaDecl(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final MetaDeclContext metaDecl() throws RecognitionException {
@@ -940,6 +1015,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitJsonObj(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitJsonObj(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final JsonObjContext jsonObj() throws RecognitionException {
@@ -1019,6 +1099,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitJsonPair(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitJsonPair(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final JsonPairContext jsonPair() throws RecognitionException {
@@ -1074,6 +1159,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitJsonVal(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitJsonVal(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final JsonValContext jsonVal() throws RecognitionException {
@@ -1198,6 +1288,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitJsonArr(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitJsonArr(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final JsonArrContext jsonArr() throws RecognitionException {
@@ -1276,6 +1371,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitTerms(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitTerms(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final TermsContext terms() throws RecognitionException {
@@ -1352,6 +1452,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitTermItem(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitTermItem(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final TermItemContext termItem() throws RecognitionException {
@@ -1405,6 +1510,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitTermEq(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitTermEq(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final TermEqContext termEq() throws RecognitionException {
@@ -1467,6 +1577,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitTerm(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitTerm(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final TermContext term() throws RecognitionException {
@@ -1557,6 +1672,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitMtdRef(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitMtdRef(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final MtdRefContext mtdRef() throws RecognitionException {
@@ -1613,6 +1733,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitJavaFqn(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitJavaFqn(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final JavaFqnContext javaFqn() throws RecognitionException {
@@ -1690,6 +1815,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitTermId(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitTermId(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final TermIdContext termId() throws RecognitionException {
@@ -1743,6 +1873,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitParExpr(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitParExpr(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 	public static class EqExprContext extends ExprContext {
 		public Token op;
@@ -1763,6 +1898,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitEqExpr(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitEqExpr(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 	public static class UnaryExprContext extends ExprContext {
 		public Token op;
@@ -1780,6 +1920,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitUnaryExpr(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitUnaryExpr(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 	public static class CompExprContext extends ExprContext {
 		public Token op;
@@ -1802,6 +1947,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitCompExpr(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitCompExpr(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 	public static class AtomExprContext extends ExprContext {
 		public AtomContext atom() {
@@ -1816,6 +1966,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitAtomExpr(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitAtomExpr(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 	public static class CallExprContext extends ExprContext {
 		public TerminalNode FUN_NAME() { return getToken(NCIntentDslParser.FUN_NAME, 0); }
@@ -1833,6 +1988,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitCallExpr(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitCallExpr(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 	public static class MultExprContext extends ExprContext {
 		public Token op;
@@ -1854,6 +2014,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitMultExpr(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitMultExpr(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 	public static class PlusExprContext extends ExprContext {
 		public Token op;
@@ -1874,6 +2039,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitPlusExpr(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitPlusExpr(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 	public static class LogExprContext extends ExprContext {
 		public Token op;
@@ -1894,6 +2064,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitLogExpr(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitLogExpr(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final ExprContext expr() throws RecognitionException {
@@ -2146,6 +2321,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitParamList(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitParamList(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final ParamListContext paramList() throws RecognitionException {
@@ -2226,6 +2406,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitAtom(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitAtom(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final AtomContext atom() throws RecognitionException {
@@ -2314,6 +2499,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitQstring(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitQstring(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final QstringContext qstring() throws RecognitionException {
@@ -2365,6 +2555,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitMinMax(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitMinMax(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final MinMaxContext minMax() throws RecognitionException {
@@ -2421,6 +2616,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitMinMaxShortcut(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitMinMaxShortcut(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final MinMaxShortcutContext minMaxShortcut() throws RecognitionException {
@@ -2473,6 +2673,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitMinMaxRange(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitMinMaxRange(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final MinMaxRangeContext minMaxRange() throws RecognitionException {
@@ -2519,6 +2724,11 @@ public class NCIntentDslParser extends Parser {
 		public void exitRule(ParseTreeListener listener) {
 			if ( listener instanceof NCIntentDslListener ) ((NCIntentDslListener)listener).exitId(this);
 		}
+		@Override
+		public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
+			if ( visitor instanceof NCIntentDslVisitor ) return ((NCIntentDslVisitor<? extends T>)visitor).visitId(this);
+			else return visitor.visitChildren(this);
+		}
 	}
 
 	public final IdContext id() throws RecognitionException {
diff --git a/nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslVisitor.java b/nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslVisitor.java
new file mode 100644
index 0000000..5e1f310
--- /dev/null
+++ b/nlpcraft/gen/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslVisitor.java
@@ -0,0 +1,274 @@
+// Generated from C:/Users/Nikita Ivanov/Documents/GitHub/incubator-nlpcraft/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4\NCIntentDsl.g4 by ANTLR 4.9.1
+package org.apache.nlpcraft.model.intent.compiler.antlr4;
+import org.antlr.v4.runtime.tree.ParseTreeVisitor;
+
+/**
+ * This interface defines a complete generic visitor for a parse tree produced
+ * by {@link NCIntentDslParser}.
+ *
+ * @param <T> The return type of the visit operation. Use {@link Void} for
+ * operations with no return type.
+ */
+public interface NCIntentDslVisitor<T> extends ParseTreeVisitor<T> {
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#dsl}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitDsl(NCIntentDslParser.DslContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#synonym}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitSynonym(NCIntentDslParser.SynonymContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#alias}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitAlias(NCIntentDslParser.AliasContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#dslItems}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitDslItems(NCIntentDslParser.DslItemsContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#dslItem}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitDslItem(NCIntentDslParser.DslItemContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#frag}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitFrag(NCIntentDslParser.FragContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#fragId}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitFragId(NCIntentDslParser.FragIdContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#fragRef}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitFragRef(NCIntentDslParser.FragRefContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#fragMeta}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitFragMeta(NCIntentDslParser.FragMetaContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#intent}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitIntent(NCIntentDslParser.IntentContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#intentId}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitIntentId(NCIntentDslParser.IntentIdContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#orderedDecl}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitOrderedDecl(NCIntentDslParser.OrderedDeclContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#mtdDecl}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitMtdDecl(NCIntentDslParser.MtdDeclContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#flowDecl}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitFlowDecl(NCIntentDslParser.FlowDeclContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#metaDecl}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitMetaDecl(NCIntentDslParser.MetaDeclContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#jsonObj}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitJsonObj(NCIntentDslParser.JsonObjContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#jsonPair}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitJsonPair(NCIntentDslParser.JsonPairContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#jsonVal}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitJsonVal(NCIntentDslParser.JsonValContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#jsonArr}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitJsonArr(NCIntentDslParser.JsonArrContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#terms}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitTerms(NCIntentDslParser.TermsContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#termItem}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitTermItem(NCIntentDslParser.TermItemContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#termEq}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitTermEq(NCIntentDslParser.TermEqContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#term}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitTerm(NCIntentDslParser.TermContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#mtdRef}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitMtdRef(NCIntentDslParser.MtdRefContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#javaFqn}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitJavaFqn(NCIntentDslParser.JavaFqnContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#termId}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitTermId(NCIntentDslParser.TermIdContext ctx);
+	/**
+	 * Visit a parse tree produced by the {@code parExpr}
+	 * labeled alternative in {@link NCIntentDslParser#expr}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitParExpr(NCIntentDslParser.ParExprContext ctx);
+	/**
+	 * Visit a parse tree produced by the {@code eqExpr}
+	 * labeled alternative in {@link NCIntentDslParser#expr}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitEqExpr(NCIntentDslParser.EqExprContext ctx);
+	/**
+	 * Visit a parse tree produced by the {@code unaryExpr}
+	 * labeled alternative in {@link NCIntentDslParser#expr}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitUnaryExpr(NCIntentDslParser.UnaryExprContext ctx);
+	/**
+	 * Visit a parse tree produced by the {@code compExpr}
+	 * labeled alternative in {@link NCIntentDslParser#expr}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitCompExpr(NCIntentDslParser.CompExprContext ctx);
+	/**
+	 * Visit a parse tree produced by the {@code atomExpr}
+	 * labeled alternative in {@link NCIntentDslParser#expr}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitAtomExpr(NCIntentDslParser.AtomExprContext ctx);
+	/**
+	 * Visit a parse tree produced by the {@code callExpr}
+	 * labeled alternative in {@link NCIntentDslParser#expr}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitCallExpr(NCIntentDslParser.CallExprContext ctx);
+	/**
+	 * Visit a parse tree produced by the {@code multExpr}
+	 * labeled alternative in {@link NCIntentDslParser#expr}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitMultExpr(NCIntentDslParser.MultExprContext ctx);
+	/**
+	 * Visit a parse tree produced by the {@code plusExpr}
+	 * labeled alternative in {@link NCIntentDslParser#expr}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitPlusExpr(NCIntentDslParser.PlusExprContext ctx);
+	/**
+	 * Visit a parse tree produced by the {@code logExpr}
+	 * labeled alternative in {@link NCIntentDslParser#expr}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitLogExpr(NCIntentDslParser.LogExprContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#paramList}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitParamList(NCIntentDslParser.ParamListContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#atom}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitAtom(NCIntentDslParser.AtomContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#qstring}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitQstring(NCIntentDslParser.QstringContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#minMax}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitMinMax(NCIntentDslParser.MinMaxContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#minMaxShortcut}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitMinMaxShortcut(NCIntentDslParser.MinMaxShortcutContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#minMaxRange}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitMinMaxRange(NCIntentDslParser.MinMaxRangeContext ctx);
+	/**
+	 * Visit a parse tree produced by {@link NCIntentDslParser#id}.
+	 * @param ctx the parse tree
+	 * @return the visitor result
+	 */
+	T visitId(NCIntentDslParser.IdContext ctx);
+}
\ No newline at end of file
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/common/package.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/package.scala
index 29b2a92..ca87d7e 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/common/package.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/package.scala
@@ -39,9 +39,6 @@ package object common {
     final val DEEP_DEBUG = false
     
     // Model and token **internal** metadata keys.
-    final val MDL_META_ALL_ELM_IDS_KEY = "__NLPCRAFT_MDL_META_ALL_ELM_IDS"
-    final val MDL_META_ALL_GRP_IDS_KEY = "__NLPCRAFT_MDL_META_ALL_GRP_IDS"
-    final val MDL_META_ALL_ALIASES_KEY = "__NLPCRAFT_MDL_META_ALL_ALIASES"
     final val TOK_META_ALIASES_KEY = "__NLPCRAFT_TOK_META_ALIASES"
     final val MDL_META_MODEL_CLASS_KEY = "__NLPCRAFT_MDL_CLASS_NAME"
 
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/impl/json/NCModelJson.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/impl/json/NCModelJson.java
index 660a7af..3040c60 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/impl/json/NCModelJson.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/impl/json/NCModelJson.java
@@ -254,9 +254,7 @@ public class NCModelJson {
     public boolean isMaxSynonymsThresholdError() {
         return maxSynonymsThresholdError;
     }
-    public void setMaxSynonymsThresholdError(boolean maxSynonymsThresholdError) {
-        this.maxSynonymsThresholdError = maxSynonymsThresholdError;
-    }
+    public void setMaxSynonymsThresholdError(boolean maxSynonymsThresholdError) { this.maxSynonymsThresholdError = maxSynonymsThresholdError; }
     public long getConversationTimeout() {
         return conversationTimeout;
     }
@@ -272,7 +270,5 @@ public class NCModelJson {
     public Map<String, String[]> getRestrictedCombinations() {
         return restrictedCombinations;
     }
-    public void setRestrictedCombinations(Map<String, String[]> restrictedCombinations) {
-        this.restrictedCombinations = restrictedCombinations;
-    }
+    public void setRestrictedCombinations(Map<String, String[]> restrictedCombinations) { this.restrictedCombinations = restrictedCombinations;}
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslBaselCompiler.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCIntentDslBaselCompiler.scala
similarity index 87%
rename from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslBaselCompiler.scala
rename to nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCIntentDslBaselCompiler.scala
index f31286e..44d9a2a 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslBaselCompiler.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCIntentDslBaselCompiler.scala
@@ -15,21 +15,20 @@
  * limitations under the License.
  */
 
-package org.apache.nlpcraft.model.intent.impl
+package org.apache.nlpcraft.model.intent.compiler
 
-import org.antlr.v4.runtime.tree.{TerminalNode ⇒ TN}
-import org.antlr.v4.runtime.{ParserRuleContext ⇒ PRC}
 import org.apache.commons.lang3.StringUtils
-import org.apache.nlpcraft.common._
+import org.apache.nlpcraft.common.{NCE, U}
 import org.apache.nlpcraft.model.NCToken
 import org.apache.nlpcraft.model.intent.utils.{NCDslTermContext, NCDslTermRetVal}
+import org.antlr.v4.runtime.{ParserRuleContext ⇒ PRC}
+import org.antlr.v4.runtime.tree.{TerminalNode ⇒ TN}
 
-import java.lang.{Double ⇒ JDouble, Long ⇒ JLong}
+import java.lang.{Long ⇒ JLong, Double ⇒ JDouble}
 import java.time.LocalDate
 import java.util.{Collections, ArrayList ⇒ JArrayList, HashMap ⇒ JHashMap}
 import scala.collection.mutable
 
-//noinspection DuplicatedCode
 trait NCIntentDslBaselCompiler {
     def syntaxError(errMsg: String, srcName: String, line: Int, pos: Int): NCE
     def runtimeError(errMsg: String, srcName: String, line: Int, pos: Int, cause: Exception = null): NCE
@@ -45,12 +44,13 @@ trait NCIntentDslBaselCompiler {
 
         syntaxError(errMsg, tok.getTokenSource.getSourceName, tok.getLine, tok.getCharPositionInLine)
     }
+
     /**
-      *
-      * @param errMsg
-      * @param ctx
-      * @return
-      */
+     *
+     * @param errMsg
+     * @param ctx
+     * @return
+     */
     def newRuntimeError(errMsg: String, cause: Exception = null)(implicit ctx: PRC): NCE = {
         val tok = ctx.start
 
@@ -58,29 +58,26 @@ trait NCIntentDslBaselCompiler {
     }
 
     type StackType = mutable.ArrayStack[NCDslTermRetVal]
-    type Instr = (NCToken, StackType,  NCDslTermContext) ⇒ Unit
+    type Instr = (NCToken, StackType, NCDslTermContext) ⇒ Unit
 
     //noinspection ComparingUnrelatedTypes
     def isJLong(v: Object): Boolean = v.isInstanceOf[JLong]
     //noinspection ComparingUnrelatedTypes
     def isJDouble(v: Object): Boolean = v.isInstanceOf[JDouble]
     //noinspection ComparingUnrelatedTypes
-    def isBoolean(v: Object): Boolean = v.isInstanceOf[Boolean]
-    def isString(v: Object): Boolean = v.isInstanceOf[String]
+    def isBool(v: Object): Boolean = v.isInstanceOf[Boolean]
+    def isStr(v: Object): Boolean = v.isInstanceOf[String]
     def isToken(v: Object): Boolean = v.isInstanceOf[NCToken]
     def asJLong(v: Object): Long = v.asInstanceOf[JLong].longValue()
     def asJDouble(v: Object): Double = v.asInstanceOf[JDouble].doubleValue()
-    def asString(v: Object): String = v.asInstanceOf[String]
+    def asStr(v: Object): String = v.asInstanceOf[String]
+    def asToken(v: Object): NCToken = v.asInstanceOf[NCToken]
     def asBool(v: Object): Boolean = v.asInstanceOf[Boolean]
 
-    def pushAny(any: Object, usedTok: Boolean)(implicit stack: StackType): Unit =
-        stack.push(NCDslTermRetVal(any, usedTok))
-    def pushLong(any: Long, usedTok: Boolean)(implicit stack: StackType): Unit =
-        stack.push(NCDslTermRetVal(Long.box(any), usedTok))
-    def pushDouble(any: Double, usedTok: Boolean)(implicit stack: StackType): Unit =
-        stack.push(NCDslTermRetVal(Double.box(any), usedTok))
-    def pushBool(any: Boolean, usedTok: Boolean)(implicit stack: StackType): Unit =
-        stack.push(NCDslTermRetVal(Boolean.box(any), usedTok))
+    def pushAny(any: Object, usedTok: Boolean)(implicit stack: StackType): Unit = stack.push(NCDslTermRetVal(any, usedTok))
+    def pushLong(any: Long, usedTok: Boolean)(implicit stack: StackType): Unit = stack.push(NCDslTermRetVal(Long.box(any), usedTok))
+    def pushDouble(any: Double, usedTok: Boolean)(implicit stack: StackType): Unit = stack.push(NCDslTermRetVal(Double.box(any), usedTok))
+    def pushBool(any: Boolean, usedTok: Boolean)(implicit stack: StackType): Unit = stack.push(NCDslTermRetVal(Boolean.box(any), usedTok))
 
     // Runtime errors.
     def rtUnaryOpError(op: String, v: Object)(implicit ctx: PRC): NCE =
@@ -110,6 +107,7 @@ trait NCIntentDslBaselCompiler {
 
         (val1, val2, f1, f2)
     }
+
     /**
      *
      * @param stack
@@ -231,12 +229,12 @@ trait NCIntentDslBaselCompiler {
      * @param or
      * @return
      */
-    def parseLogExpr(and: TN, or : TN)(implicit ctx: PRC): Instr = (_, stack: StackType, _) ⇒ {
+    def parseLogExpr(and: TN, or: TN)(implicit ctx: PRC): Instr = (_, stack: StackType, _) ⇒ {
         implicit val s: StackType = stack
 
         val (v1, v2, f1, f2) = pop2()
 
-        if (!isBoolean(v1) || !isBoolean(v2))
+        if (!isBool(v1) || !isBool(v2))
             throw rtBinaryOpError(if (and != null) "&&" else "||", v1, v2)
 
         if (and != null)
@@ -291,7 +289,7 @@ trait NCIntentDslBaselCompiler {
         val usedTok = f1 || f2
 
         if (plus != null) {
-            if (isString(v1) && isString(v2)) pushAny(asString(v1) + asString(v2), usedTok)
+            if (isStr(v1) && isStr(v2)) pushAny(asStr(v1) + asStr(v2), usedTok)
             else if (isJLong(v1) && isJLong(v2)) pushLong(asJLong(v1) + asJLong(v2), usedTok)
             else if (isJLong(v1) && isJDouble(v2)) pushDouble(asJLong(v1) + asJDouble(v2), usedTok)
             else if (isJDouble(v1) && isJLong(v2)) pushDouble(asJDouble(v1) + asJLong(v2), usedTok)
@@ -331,7 +329,7 @@ trait NCIntentDslBaselCompiler {
         else {
             assert(not != null)
 
-            if (isBoolean(v)) pushBool(!asBool(v), usedTok)
+            if (isBool(v)) pushBool(!asBool(v), usedTok)
             else
                 throw rtUnaryOpError("!", v)
         }
@@ -386,11 +384,12 @@ trait NCIntentDslBaselCompiler {
 
             val (v, f) = pop1()
 
-            if (!isString(v))
+            if (!isStr(v))
                 throw rtParamTypeError(fun, v, "string")
 
-            (asString(v), f)
+            (asStr(v), f)
         }
+
         def get1Double(): (JDouble, Boolean) = {
             ensureStack(1)
 
@@ -401,9 +400,10 @@ trait NCIntentDslBaselCompiler {
 
             (asJDouble(v), f)
         }
+
         def get2Doubles(): (JDouble, JDouble, Boolean) = {
             ensureStack(2)
-            
+
             val (v1, v2, f1, f2) = pop2()
 
             if (!isJDouble(v1))
@@ -413,37 +413,42 @@ trait NCIntentDslBaselCompiler {
 
             (asJDouble(v1), asJDouble(v2), f1 || f2)
         }
-        def get1Any(): (Any, Boolean) = {
-            ensureStack(1)
-
-            pop1()
-        }
 
-        def doSplit(): Unit = {
+        def get2Str(): (String, String, Boolean) = {
             ensureStack(2)
 
             val (v1, v2, f1, f2) = pop2()
 
-            if (!isString(v1))
+            if (!isStr(v1))
                 throw rtParamTypeError(fun, v1, "string")
-            if (!isString(v2))
+            if (!isStr(v2))
                 throw rtParamTypeError(fun, v2, "string")
 
-            asString(v1).split(asString(v2)).foreach { pushAny(_, f1 || f2) }
+            (asStr(v1), asStr(v2), f1 || f2)
         }
-        def doSplitTrim(): Unit = {
+
+        def get1Tok1Str(): (NCToken, String, Boolean) = {
             ensureStack(2)
 
             val (v1, v2, f1, f2) = pop2()
 
-            if (!isString(v1))
-                throw rtParamTypeError(fun, v1, "string")
-            if (!isString(v2))
+            if (!isToken(v1))
+                throw rtParamTypeError(fun, v1, "token")
+            if (!isStr(v2))
                 throw rtParamTypeError(fun, v2, "string")
 
-            asString(v1).split(asString(v2)).foreach { s ⇒ pushAny(s.strip, f1 || f2) }
+            (asToken(v1), asStr(v2), f1 || f2)
         }
 
+        def get1Any(): (Any, Boolean) = {
+            ensureStack(1)
+
+            pop1()
+        }
+
+        def doSplit(): Unit = get2Str() match { case (s1, s2, f) ⇒  s1.split(asStr(s2)).foreach { pushAny(_, f) }}
+        def doSplitTrim(): Unit = get2Str() match { case (s1, s2, f) ⇒  s1.split(asStr(s2)).foreach { s ⇒ pushAny(s.strip, f) }}
+
         /*
          * Collection, statistical operations.
          */
@@ -460,6 +465,7 @@ trait NCIntentDslBaselCompiler {
 
             pushAny(jl, f)
         }
+
         def doMap(): Unit = {
             if (stack.size % 2 != 0)
                 throw rtParamNumError(fun)
@@ -488,18 +494,7 @@ trait NCIntentDslBaselCompiler {
         /*
          * Metadata operations.
          */
-        def doPartMeta(): Unit = {
-            ensureStack(2)
-
-            val (v1, v2, f1, f2) = pop2()
-
-            if (!isToken(v1))
-                throw rtParamTypeError(fun, v1, "token")
-            if (!isString(v2))
-                throw rtParamTypeError(fun, v2, "string")
-
-            pushAny(v1.asInstanceOf[NCToken].meta(v2.asInstanceOf[String]), f1 || f2)
-        }
+        def doPartMeta(): Unit = get1Tok1Str() match { case (t, s, f) ⇒  pushAny(t.meta(s), f) }
 
         /*
          * Math operations.
@@ -509,19 +504,23 @@ trait NCIntentDslBaselCompiler {
             case (a: JDouble, f) ⇒ pushDouble(Math.abs(a), f)
             case x ⇒ throw rtParamTypeError(fun, x, "numeric")
         }
+
         def doSquare(): Unit = get1Any() match {
             case (a: JLong, f) ⇒ pushLong(a * a, f)
             case (a: JDouble, f) ⇒ pushDouble(a * a, f)
             case x ⇒ throw rtParamTypeError(fun, x, "numeric")
         }
 
-        def doJson(): Unit = get1Str() match { case (s, f) ⇒ pushAny(U.jsonToJavaMap(asString(s)), f) }
+        def doJson(): Unit = get1Str() match {
+            case (s, f) ⇒ pushAny(U.jsonToJavaMap(asStr(s)), f)
+        }
+
         def doIf(): Unit = {
             ensureStack(3)
 
             val (v1, v2, v3, f1, f2, f3) = pop3()
 
-            if (!isBoolean(v1))
+            if (!isBool(v1))
                 throw rtParamTypeError(fun, v1, "boolean")
 
             if (asBool(v1))
@@ -534,17 +533,7 @@ trait NCIntentDslBaselCompiler {
             if (stack.nonEmpty && stack.top.isInstanceOf[NCToken]) stack.top.asInstanceOf[NCToken] else tok
 
         def doPart(): Unit = {
-            ensureStack(2)
-
-            val (v1, v2, f1, f2) = pop2()
-
-            if (!isToken(v1))
-                throw rtParamTypeError(fun, v1, "token")
-            if (!isString(v2))
-                throw rtParamTypeError(fun, v2, "string")
-
-            val t = v1.asInstanceOf[NCToken]
-            val aliasId = v2.asInstanceOf[String]
+            val (t, aliasId, f) = get1Tok1Str()
 
             val parts = t.findPartTokens(aliasId)
 
@@ -552,28 +541,17 @@ trait NCIntentDslBaselCompiler {
                 throw newRuntimeError(s"Cannot find part for token (use 'parts' function instead) [" +
                     s"id=${t.getId}, " +
                     s"aliasId=$aliasId" +
-                s"]")
+                    s"]")
             else if (parts.size() > 1)
                 throw newRuntimeError(s"Too many parts found for token (use 'parts' function instead) [" +
                     s"id=${t.getId}, " +
                     s"aliasId=$aliasId" +
-                s"]")
+                    s"]")
 
-            pushAny(parts.get(0), f1 || f2)
+            pushAny(parts.get(0), f)
         }
 
-        def doParts(): Unit = {
-            ensureStack(2)
-
-            val (v1, v2, f1, f2) = pop2()
-
-            if (!isToken(v1))
-                throw rtParamTypeError(fun, v1, "token")
-            if (!isString(v2))
-                throw rtParamTypeError(fun, v2, "string")
-
-            pushAny(v1.asInstanceOf[NCToken].findPartTokens(v2.asInstanceOf[String]), f1 || f2)
-        }
+        def doParts(): Unit = get1Tok1Str() match { case (t, aliasId, f) ⇒ pushAny(t.findPartTokens(aliasId), f) }
 
         fun match {
             // Metadata access.
@@ -637,13 +615,13 @@ trait NCIntentDslBaselCompiler {
             case "strip" ⇒ get1Str() match { case (s, f) ⇒ pushAny(s.trim, f) }
             case "uppercase" ⇒ get1Str() match { case (s, f) ⇒ pushAny(s.toUpperCase, f) }
             case "lowercase" ⇒ get1Str() match { case (s, f) ⇒ pushAny(s.toLowerCase, f) }
-            case "is_alpha" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlpha(asString(s)), f) }
-            case "is_alphanum" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlphanumeric(asString(s)), f) }
-            case "is_whitespace" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isWhitespace(asString(s)), f) }
-            case "is_num" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isNumeric(asString(s)), f) }
-            case "is_numspace" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isNumericSpace(asString(s)), f) }
-            case "is_alphaspace" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlphaSpace(asString(s)), f) }
-            case "is_alphanumspace" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlphanumericSpace(asString(s)), f) }
+            case "is_alpha" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlpha(asStr(s)), f) }
+            case "is_alphanum" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlphanumeric(asStr(s)), f) }
+            case "is_whitespace" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isWhitespace(asStr(s)), f) }
+            case "is_num" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isNumeric(asStr(s)), f) }
+            case "is_numspace" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isNumericSpace(asStr(s)), f) }
+            case "is_alphaspace" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlphaSpace(asStr(s)), f) }
+            case "is_alphanumspace" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlphanumericSpace(asStr(s)), f) }
             case "substring" ⇒
             case "charAt" ⇒
             case "regex" ⇒
@@ -654,11 +632,11 @@ trait NCIntentDslBaselCompiler {
 
             // Math functions.
             case "abs" ⇒ doAbs()
-            case "ceil" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.ceil(a), f) }
-            case "floor" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.floor(a), f) }
-            case "rint" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.rint(a), f) }
-            case "round" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushLong(Math.round(a), f) }
-            case "signum" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.signum(a), f) }
+            case "ceil" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.ceil(a), f) } 
+            case "floor" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.floor(a), f) } 
+            case "rint" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.rint(a), f) } 
+            case "round" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushLong(Math.round(a), f) } 
+            case "signum" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.signum(a), f) } 
             case "sqrt" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.sqrt(a), f) }
             case "cbrt" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.cbrt(a), f) }
             case "pi" ⇒ pushDouble(Math.PI, false)
@@ -716,18 +694,18 @@ trait NCIntentDslBaselCompiler {
             case "sum" ⇒
 
             // Date-time functions.
-            case "year" ⇒ pushLong(LocalDate.now.getYear,false) // 2021.
-            case "month" ⇒ pushLong(LocalDate.now.getMonthValue,false) // 1 ... 12.
-            case "day_of_month" ⇒ pushLong(LocalDate.now.getDayOfMonth,false) // 1 ... 31.
-            case "day_of_week" ⇒ pushLong(LocalDate.now.getDayOfWeek.getValue,false)
-            case "day_of_year" ⇒ pushLong(LocalDate.now.getDayOfYear,false)
+            case "year" ⇒ pushLong(LocalDate.now.getYear, false) // 2021.
+            case "month" ⇒ pushLong(LocalDate.now.getMonthValue, false) // 1 ... 12.
+            case "day_of_month" ⇒ pushLong(LocalDate.now.getDayOfMonth, false) // 1 ... 31.
+            case "day_of_week" ⇒ pushLong(LocalDate.now.getDayOfWeek.getValue, false)
+            case "day_of_year" ⇒ pushLong(LocalDate.now.getDayOfYear, false)
             case "hour" ⇒
             case "minute" ⇒
             case "second" ⇒
             case "week_of_month" ⇒
             case "week_of_year" ⇒
             case "quarter" ⇒
-            case "now" ⇒ pushLong(System.currentTimeMillis(),false) // Epoc time.
+            case "now" ⇒ pushLong(System.currentTimeMillis(), false) // Epoc time.
 
             case _ ⇒ throw rtUnknownFunError(fun) // Assertion.
         }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslCompiler.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCIntentDslCompiler.scala
similarity index 87%
rename from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslCompiler.scala
rename to nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCIntentDslCompiler.scala
index 691af29..55793c2 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslCompiler.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCIntentDslCompiler.scala
@@ -15,21 +15,21 @@
  * limitations under the License.
  */
 
-package org.apache.nlpcraft.model.intent.impl
+package org.apache.nlpcraft.model.intent.compiler
 
 import com.typesafe.scalalogging.LazyLogging
-import org.antlr.v4.runtime._
 import org.antlr.v4.runtime.tree.ParseTreeWalker
+import org.antlr.v4.runtime._
 import org.apache.nlpcraft.common._
-import org.apache.nlpcraft.model._
-import org.apache.nlpcraft.model.intent.impl.antlr4.{NCIntentDslParser ⇒ IDP, _}
-import org.apache.nlpcraft.model.intent.impl.{NCIntentDslFragmentCache ⇒ FragCache}
+import org.apache.nlpcraft.model.intent.compiler.antlr4.{NCIntentDslBaseListener, NCIntentDslLexer, NCIntentDslParser ⇒ IDP}
 import org.apache.nlpcraft.model.intent.utils._
+import org.apache.nlpcraft.model.intent.compiler.{NCIntentDslFragmentCache ⇒ FragCache}
+import org.apache.nlpcraft.model._
+import scala.collection.JavaConverters._
 
 import java.nio.file.Path
 import java.util.Optional
 import java.util.regex.{Pattern, PatternSyntaxException}
-import scala.collection.JavaConverters._
 import scala.collection.mutable
 import scala.collection.mutable.ArrayBuffer
 
@@ -44,8 +44,12 @@ object NCIntentDslCompiler extends LazyLogging {
      * @param mdlId
      */
     class FiniteStateMachine(dsl: String, mdlId: String) extends NCIntentDslBaseListener with NCIntentDslBaselCompiler {
-        // Accumulator for parsed intents.
+        // Accumulators for parsed objects.
         private val intents = ArrayBuffer.empty[NCDslIntent]
+        private var synonym: NCDslSynonym = _
+
+        // Synonym.
+        private var alias: String = _
 
         // Fragment components.
         private var fragId: String = _
@@ -70,27 +74,27 @@ object NCIntentDslCompiler extends LazyLogging {
         private var refClsName: Option[String] = None
         private var refMtdName: Option[String] = None
 
-        // Current term's code, i.e. list of instructions.
-        private var termInstrs = mutable.Buffer.empty[Instr]
+        // Current expression code, i.e. list of instructions.
+        private var instrs = mutable.Buffer.empty[Instr]
 
         /*
          * Shared/common implementation.
          */
-        override def exitUnaryExpr(ctx: IDP.UnaryExprContext): Unit = termInstrs += parseUnaryExpr(ctx.MINUS(), ctx.NOT())(ctx)
+        override def exitUnaryExpr(ctx: IDP.UnaryExprContext): Unit = instrs += parseUnaryExpr(ctx.MINUS(), ctx.NOT())(ctx)
 
-        override def exitMultExpr(ctx: IDP.MultExprContext): Unit = termInstrs += parseMultExpr(ctx.MULT(), ctx.MOD(), ctx.DIV())(ctx)
+        override def exitMultExpr(ctx: IDP.MultExprContext): Unit = instrs += parseMultExpr(ctx.MULT(), ctx.MOD(), ctx.DIV())(ctx)
 
-        override def exitPlusExpr(ctx: IDP.PlusExprContext): Unit = termInstrs += parsePlusExpr(ctx.PLUS(), ctx.MINUS())(ctx)
+        override def exitPlusExpr(ctx: IDP.PlusExprContext): Unit = instrs += parsePlusExpr(ctx.PLUS(), ctx.MINUS())(ctx)
 
-        override def exitCompExpr(ctx: IDP.CompExprContext): Unit = termInstrs += parseCompExpr(ctx.LT(), ctx.GT(), ctx.LTEQ(), ctx.GTEQ())(ctx)
+        override def exitCompExpr(ctx: IDP.CompExprContext): Unit = instrs += parseCompExpr(ctx.LT(), ctx.GT(), ctx.LTEQ(), ctx.GTEQ())(ctx)
 
-        override def exitLogExpr(ctx: IDP.LogExprContext): Unit = termInstrs += parseLogExpr(ctx.AND, ctx.OR())(ctx)
+        override def exitLogExpr(ctx: IDP.LogExprContext): Unit = instrs += parseLogExpr(ctx.AND, ctx.OR())(ctx)
 
-        override def exitEqExpr(ctx: IDP.EqExprContext): Unit = termInstrs += parseEqExpr(ctx.EQ, ctx.NEQ())(ctx)
+        override def exitEqExpr(ctx: IDP.EqExprContext): Unit = instrs += parseEqExpr(ctx.EQ, ctx.NEQ())(ctx)
 
-        override def exitCallExpr(ctx: IDP.CallExprContext): Unit = termInstrs += parseCallExpr(ctx.FUN_NAME())(ctx)
+        override def exitCallExpr(ctx: IDP.CallExprContext): Unit = instrs += parseCallExpr(ctx.FUN_NAME())(ctx)
 
-        override def exitAtom(ctx: IDP.AtomContext): Unit = termInstrs += parseAtom(ctx.getText)(ctx)
+        override def exitAtom(ctx: IDP.AtomContext): Unit = instrs += parseAtom(ctx.getText)(ctx)
 
         /**
          *
@@ -146,6 +150,35 @@ object NCIntentDslCompiler extends LazyLogging {
                 throw newSyntaxError(s"Duplicate intent ID: $intentId")(ctx.id())
         }
 
+
+        override def exitAlias(ctx: IDP.AliasContext): Unit = {
+            alias = ctx.id().getText
+        }
+
+        override def exitSynonym(ctx: IDP.SynonymContext): Unit = {
+            implicit val evidence: ParserRuleContext = ctx
+
+            val code = mutable.Buffer.empty[Instr] ++ instrs // Local copy.
+
+            synonym = NCDslSynonym(
+                Option(alias),
+                (tok: NCToken, termCtx: NCDslTermContext) ⇒ {
+                    val stack = new mutable.ArrayStack[NCDslTermRetVal]()
+
+                    // Execute all instructions.
+                    code.foreach(_ (tok, stack, termCtx))
+
+                    // Pop final result from stack.
+                    val x = stack.pop()
+
+                    if (!isBool(x.retVal))
+                        throw newRuntimeError(s"Synonym does not return boolean value: ${ctx.getText}")
+
+                    asBool(x.retVal)
+                }
+            )
+        }
+
         override def exitFragId(ctx: IDP.FragIdContext): Unit = {
             fragId = ctx.id().getText
 
@@ -264,25 +297,24 @@ object NCIntentDslCompiler extends LazyLogging {
                     }
                 }
                 else { // DSL-defined term.
-                    val instrs = mutable.Buffer.empty[Instr]
+                    val code = mutable.Buffer.empty[Instr]
 
-                    instrs ++= termInstrs
+                    code ++= instrs
 
                     (tok: NCToken, termCtx: NCDslTermContext) ⇒ {
                         val stack = new mutable.ArrayStack[NCDslTermRetVal]()
 
                         // Execute all instructions.
-                        instrs.foreach(_ (tok, stack, termCtx))
+                        code.foreach(_ (tok, stack, termCtx))
 
                         // Pop final result from stack.
                         val x = stack.pop()
 
-                        if (!isBoolean(x.retVal))
+                        if (!isBool(x.retVal))
                             throw newRuntimeError(s"Intent term does not return boolean value: ${ctx.getText}")
 
                         (asBool(x.retVal), x.usedTok)
                     }
-
                 }
 
             // Add term.
@@ -297,7 +329,7 @@ object NCIntentDslCompiler extends LazyLogging {
             // Reset term vars.
             setMinMax(1, 1)
             termId = null
-            termInstrs.clear()
+            instrs.clear()
             refClsName = None
             refMtdName = None
         }
@@ -336,7 +368,7 @@ object NCIntentDslCompiler extends LazyLogging {
          *
          * @return
          */
-        def getCompiledSynonym: NCDslSynonym = ???
+        def getCompiledSynonym: NCDslSynonym = synonym
 
         override def syntaxError(errMsg: String, srcName: String, line: Int, pos: Int): NCE =
             throw new NCE(mkSyntaxError(errMsg, srcName, line, pos, dsl, mdlId))
@@ -520,7 +552,7 @@ object NCIntentDslCompiler extends LazyLogging {
      * accumulated in a static map keyed by model ID. Only intents are returned, if any.
      *
      * @param filePath *.nc intent DSL file to compile.
-     * @param mdlId ID of the model *.nc file belongs to.
+     * @param mdlId    ID of the model *.nc file belongs to.
      * @return
      */
     @throws[NCE]
@@ -533,8 +565,8 @@ object NCIntentDslCompiler extends LazyLogging {
      * Compiles inline (supplied) fragments and/or intents. Note that fragments are accumulated in a static
      * map keyed by model ID. Only intents are returned, if any.
      *
-     * @param dsl Intent DSL to compile.
-     * @param mdlId ID of the model DSL belongs to.
+     * @param dsl     Intent DSL to compile.
+     * @param mdlId   ID of the model DSL belongs to.
      * @param srcName Optional source name.
      * @return
      */
@@ -547,7 +579,7 @@ object NCIntentDslCompiler extends LazyLogging {
 
     /**
      *
-     * @param dsl Synonym DSL to compile.
+     * @param dsl   Synonym DSL to compile.
      * @param mdlId ID of the model DSL belongs to.
      * @return
      */
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslFragmentCache.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCIntentDslFragmentCache.scala
similarity index 81%
rename from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslFragmentCache.scala
rename to nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCIntentDslFragmentCache.scala
index 601a817..fbb2998 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslFragmentCache.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCIntentDslFragmentCache.scala
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.nlpcraft.model.intent.impl
+package org.apache.nlpcraft.model.intent.compiler
 
 import org.apache.nlpcraft.model.intent.utils.NCDslFragment
 
@@ -23,42 +23,42 @@ import scala.collection.concurrent.TrieMap
 import scala.collection.mutable
 
 /**
-  * Global intent DSL fragment cache.
-  */
+ * Global intent DSL fragment cache.
+ */
 object NCIntentDslFragmentCache {
-    private final val cache = TrieMap.empty[String /* Model ID. */, mutable.Map[String, NCDslFragment]]
-    
+    private final val cache = TrieMap.empty[String /* Model ID. */ , mutable.Map[String, NCDslFragment]]
+
     /**
-      *
-      */
+     *
+     */
     def clear(): Unit = cache.clear()
-    
+
     /**
-      *
-      * @param mdlId
-      */
+     *
+     * @param mdlId
+     */
     def clear(mdlId: String): Unit = cache += mdlId → mutable.HashMap.empty[String, NCDslFragment]
-    
+
     /**
-      *
-      * @param mdlId
-      * @param frag
-      */
+     *
+     * @param mdlId
+     * @param frag
+     */
     def add(mdlId: String, frag: NCDslFragment): Unit =
         cache.getOrElse(mdlId, {
             val m = mutable.HashMap.empty[String, NCDslFragment]
-            
+
             cache += mdlId → m
-            
+
             m
         }) += (frag.id → frag)
-    
+
     /**
-      *
-      * @param mdlId
-      * @param fragId
-      * @return
-      */
+     *
+     * @param mdlId
+     * @param fragId
+     * @return
+     */
     def get(mdlId: String, fragId: String): Option[NCDslFragment] =
         cache.get(mdlId).flatMap(_.get(fragId))
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDsl.g4 b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDsl.g4
similarity index 100%
rename from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDsl.g4
rename to nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDsl.g4
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDsl.interp b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDsl.interp
similarity index 100%
rename from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDsl.interp
rename to nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDsl.interp
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDsl.tokens b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDsl.tokens
similarity index 100%
rename from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDsl.tokens
rename to nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDsl.tokens
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslBaseListener.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslBaseListener.java
similarity index 99%
rename from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslBaseListener.java
rename to nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslBaseListener.java
index 3c6c2cf..f1beff5 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslBaseListener.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslBaseListener.java
@@ -1,5 +1,5 @@
 // Generated from C:/Users/Nikita Ivanov/Documents/GitHub/incubator-nlpcraft/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4\NCIntentDsl.g4 by ANTLR 4.9.1
-package org.apache.nlpcraft.model.intent.impl.antlr4;
+package org.apache.nlpcraft.model.intent.compiler.antlr4;
 
 import org.antlr.v4.runtime.ParserRuleContext;
 import org.antlr.v4.runtime.tree.ErrorNode;
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.interp b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslLexer.interp
similarity index 100%
rename from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.interp
rename to nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslLexer.interp
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslLexer.java
similarity index 99%
rename from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.java
rename to nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslLexer.java
index aeb35e2..63cae30 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslLexer.java
@@ -1,13 +1,10 @@
 // Generated from C:/Users/Nikita Ivanov/Documents/GitHub/incubator-nlpcraft/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4\NCIntentDsl.g4 by ANTLR 4.9.1
-package org.apache.nlpcraft.model.intent.impl.antlr4;
+package org.apache.nlpcraft.model.intent.compiler.antlr4;
 import org.antlr.v4.runtime.Lexer;
 import org.antlr.v4.runtime.CharStream;
-import org.antlr.v4.runtime.Token;
-import org.antlr.v4.runtime.TokenStream;
 import org.antlr.v4.runtime.*;
 import org.antlr.v4.runtime.atn.*;
 import org.antlr.v4.runtime.dfa.DFA;
-import org.antlr.v4.runtime.misc.*;
 
 @SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
 public class NCIntentDslLexer extends Lexer {
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.tokens b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslLexer.tokens
similarity index 100%
rename from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslLexer.tokens
rename to nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslLexer.tokens
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslListener.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslListener.java
similarity index 99%
rename from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslListener.java
rename to nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslListener.java
index 904069b..1a0c376 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslListener.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslListener.java
@@ -1,5 +1,5 @@
 // Generated from C:/Users/Nikita Ivanov/Documents/GitHub/incubator-nlpcraft/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4\NCIntentDsl.g4 by ANTLR 4.9.1
-package org.apache.nlpcraft.model.intent.impl.antlr4;
+package org.apache.nlpcraft.model.intent.compiler.antlr4;
 import org.antlr.v4.runtime.tree.ParseTreeListener;
 
 /**
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslParser.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslParser.java
similarity index 99%
rename from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslParser.java
rename to nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslParser.java
index 976d4c3..fa8282d 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4/NCIntentDslParser.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/antlr4/NCIntentDslParser.java
@@ -1,13 +1,10 @@
 // Generated from C:/Users/Nikita Ivanov/Documents/GitHub/incubator-nlpcraft/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/antlr4\NCIntentDsl.g4 by ANTLR 4.9.1
-package org.apache.nlpcraft.model.intent.impl.antlr4;
+package org.apache.nlpcraft.model.intent.compiler.antlr4;
 import org.antlr.v4.runtime.atn.*;
 import org.antlr.v4.runtime.dfa.DFA;
 import org.antlr.v4.runtime.*;
-import org.antlr.v4.runtime.misc.*;
 import org.antlr.v4.runtime.tree.*;
 import java.util.List;
-import java.util.Iterator;
-import java.util.ArrayList;
 
 @SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
 public class NCIntentDslParser extends Parser {
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentSolver.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/solver/NCIntentSolver.scala
similarity index 97%
rename from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentSolver.scala
rename to nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/solver/NCIntentSolver.scala
index f7dbfeb..7198adf 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentSolver.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/solver/NCIntentSolver.scala
@@ -15,10 +15,11 @@
  * limitations under the License.
  */
 
-package org.apache.nlpcraft.model.intent.impl
+package org.apache.nlpcraft.model.intent.solver
 
 import com.typesafe.scalalogging.LazyLogging
 import io.opencensus.trace.Span
+import org.apache.nlpcraft.common._
 import org.apache.nlpcraft.common.debug.NCLogHolder
 import org.apache.nlpcraft.common.opencensus.NCOpenCensusTrace
 import org.apache.nlpcraft.common.util.NCUtils
@@ -26,7 +27,7 @@ import org.apache.nlpcraft.model.impl.NCVariantImpl
 import org.apache.nlpcraft.model.intent.utils.NCDslIntent
 import org.apache.nlpcraft.model.{NCContext, NCIntentMatch, NCIntentSkip, NCModel, NCRejection, NCResult, NCToken, NCVariant}
 import org.apache.nlpcraft.probe.mgrs.dialogflow.NCDialogFlowManager
-import org.apache.nlpcraft.common._
+
 import scala.collection.JavaConverters._
 
 /**
@@ -107,7 +108,7 @@ class NCIntentSolver(intents: List[(NCDslIntent/*Intent*/, NCIntentMatch ⇒ NCR
                     override def getTermTokens(idx: Int): java.util.List[NCToken] =
                         res.groups(idx).tokens.asJava
                     override def getTermTokens(termId: String): java.util.List[NCToken] =
-                        res.groups.find(_.termId == termId).flatMap(grp ⇒ Some(grp.tokens)).getOrElse(Nil).asJava
+                        res.groups.find(_.termId === termId).flatMap(grp ⇒ Some(grp.tokens)).getOrElse(Nil).asJava
                 }
                 
                 if (!in.context.getModel.asInstanceOf[NCModel].onMatchedIntent(intentMatch)) {
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentSolverEngine.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/solver/NCIntentSolverEngine.scala
similarity index 88%
rename from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentSolverEngine.scala
rename to nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/solver/NCIntentSolverEngine.scala
index 72f5e4c..01d1c4b 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentSolverEngine.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/solver/NCIntentSolverEngine.scala
@@ -1,44 +1,28 @@
-/*
- * 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.nlpcraft.model.intent.impl
+package org.apache.nlpcraft.model.intent.solver
 
-import java.util.function.Function
 import com.typesafe.scalalogging.LazyLogging
-import org.apache.nlpcraft.common._
 import org.apache.nlpcraft.common.ascii.NCAsciiTable
 import org.apache.nlpcraft.common.debug.{NCLogGroupToken, NCLogHolder}
 import org.apache.nlpcraft.common.opencensus.NCOpenCensusTrace
-import org.apache.nlpcraft.model.intent.utils.{NCDslIntent, NCDslTerm, NCDslTermContext}
-import org.apache.nlpcraft.model._
+import org.apache.nlpcraft.common._
 import org.apache.nlpcraft.model.impl.NCTokenLogger
+import org.apache.nlpcraft.model.intent.utils.{NCDslIntent, NCDslTerm, NCDslTermContext}
+import org.apache.nlpcraft.model.{NCContext, NCIntentMatch, NCResult, NCToken}
 import org.apache.nlpcraft.probe.mgrs.dialogflow.NCDialogFlowManager
+import org.apache.nlpcraft.model.impl.NCTokenPimp._
 
-import collection.convert.ImplicitConversions._
+import java.util.function.Function
 import scala.collection.mutable
 
 /**
-  * Intent solver that finds the best matching intent given user sentence.
-  */
+ * Intent solver that finds the best matching intent given user sentence.
+ */
 object NCIntentSolverEngine extends LazyLogging with NCOpenCensusTrace {
+
     /**
      * NOTE: not thread-safe.
      */
-    private [impl] class Weight(ws: Int*) extends Ordered[Weight] {
+    private[impl] class Weight(ws: Int*) extends Ordered[Weight] {
         private var buf = mutable.ArrayBuffer[Int]()
 
         buf.appendAll(ws)
@@ -126,10 +110,10 @@ object NCIntentSolverEngine extends LazyLogging with NCOpenCensusTrace {
     }
 
     /**
-      *
-      * @param used
-      * @param token
-      */
+     *
+     * @param used
+     * @param token
+     */
     private case class UsedToken(
         var used: Boolean,
         var conv: Boolean,
@@ -137,12 +121,12 @@ object NCIntentSolverEngine extends LazyLogging with NCOpenCensusTrace {
     )
 
     /**
-      * @param termId
-      * @param usedTokens
-      * @param weight
-      */
+     * @param termId
+     * @param usedTokens
+     * @param weight
+     */
     private case class TermMatch(
-        termId: String,
+        termId: Option[String],
         usedTokens: List[UsedToken],
         weight: Weight
     ) {
@@ -150,22 +134,22 @@ object NCIntentSolverEngine extends LazyLogging with NCOpenCensusTrace {
     }
 
     /**
-      *
-      * @param termId
-      * @param usedTokens
-      */
+     *
+     * @param termId
+     * @param usedTokens
+     */
     private case class TermTokensGroup(
-        termId: String,
+        termId: Option[String],
         usedTokens: List[UsedToken]
     )
 
     /**
-      *
-      * @param tokenGroups
-      * @param weight
-      * @param intent
-      * @param exactMatch
-      */
+     *
+     * @param tokenGroups
+     * @param weight
+     * @param intent
+     * @param exactMatch
+     */
     private case class IntentMatch(
         tokenGroups: List[TermTokensGroup],
         weight: Weight,
@@ -174,17 +158,17 @@ object NCIntentSolverEngine extends LazyLogging with NCOpenCensusTrace {
     )
 
     /**
-      * Main entry point for intent engine.
-      *
-      * @param ctx Query context.
-      * @param intents Set of intents to match for.
-      * @param logHldr Log holder.
-      * @return
-      */
+     * Main entry point for intent engine.
+     *
+     * @param ctx     Query context.
+     * @param intents Set of intents to match for.
+     * @param logHldr Log holder.
+     * @return
+     */
     @throws[NCE]
     def solve(
         ctx: NCContext,
-        intents: List[(NCDslIntent/*Intent*/, NCIntentMatch ⇒ NCResult)/*Callback*/],
+        intents: List[(NCDslIntent /*Intent*/ , NCIntentMatch ⇒ NCResult) /*Callback*/ ],
         logHldr: NCLogHolder
     ): List[NCIntentSolverResult] = {
         case class MatchHolder(
@@ -321,9 +305,9 @@ object NCIntentSolverEngine extends LazyLogging with NCOpenCensusTrace {
                                 def calcHash(m: MatchHolder): Int = {
                                     val variantPart =
                                         m.variant.
-                                        tokens.
-                                        map(t ⇒ s"${t.getId}${t.getGroups}${t.getValue}${t.normText}").
-                                        mkString("")
+                                            tokens.
+                                            map(t ⇒ s"${t.getId}${t.getGroups}${t.getValue}${t.normText}").
+                                            mkString("")
 
                                     val intentPart = m.intentMatch.intent.toString
 
@@ -372,8 +356,7 @@ object NCIntentSolverEngine extends LazyLogging with NCOpenCensusTrace {
                             im.exactMatch,
                             im.weight.toSeq,
                             im.tokenGroups.map(g ⇒
-                                (if (g.termId == null) "" else g.termId) →
-                                g.usedTokens.map(t ⇒ NCLogGroupToken(t.token, t.conv, t.used))
+                                g.termId.getOrElse("") → g.usedTokens.map(t ⇒ NCLogGroupToken(t.token, t.conv, t.used))
                             ).toMap
                         )
                 })
@@ -397,10 +380,10 @@ object NCIntentSolverEngine extends LazyLogging with NCOpenCensusTrace {
     }
 
     /**
-      *
-      * @param im
-      * @return
-      */
+     *
+     * @param im
+     * @return
+     */
     private def mkPickTokens(im: IntentMatch): List[String] = {
         val buf = mutable.ListBuffer.empty[String]
 
@@ -433,12 +416,12 @@ object NCIntentSolverEngine extends LazyLogging with NCOpenCensusTrace {
     }
 
     /**
-      *
-      * @param intent
-      * @param senToks
-      * @param convToks
-      * @return
-      */
+     *
+     * @param intent
+     * @param senToks
+     * @param convToks
+     * @return
+     */
     //noinspection DuplicatedCode
     private def solveIntent(
         ctx: NCContext,
@@ -451,13 +434,13 @@ object NCIntentSolverEngine extends LazyLogging with NCOpenCensusTrace {
         val flow = NCDialogFlowManager.getDialogFlow(ctx.getRequest.getUser.getId, ctx.getModel.getId)
         val varStr = s"(variant #${varIdx + 1})"
         val flowRegex = intent.flowRegex
-        
+
         var flowMatched = true
 
         // Check dialog flow regex first, if any.
         if (intent.flowRegex.isDefined) {
             val str = flow.map(_.getIntentId).mkString(" ")
-            
+
             def x(s: String): Unit = {
                 logger.info(s"Intent '$intentId' ${bo(s)} regex dialog flow $varStr:")
                 logger.info(s"  |-- ${c("Intent IDs  :")} $str")
@@ -466,7 +449,7 @@ object NCIntentSolverEngine extends LazyLogging with NCOpenCensusTrace {
 
             if (!flowRegex.get.matcher(str).find(0)) {
                 x("did not match")
-                
+
                 flowMatched = false
             }
             else
@@ -475,14 +458,14 @@ object NCIntentSolverEngine extends LazyLogging with NCOpenCensusTrace {
         else if (intent.flowMtdName.isDefined) {
             // TODO.
         }
-        
+
         if (flowMatched) {
             val intentW = new Weight()
             val intentGrps = mutable.ListBuffer.empty[TermTokensGroup]
             var abort = false
             val ordered = intent.ordered
             var lastTermMatch: TermMatch = null
-            
+
             val termCtx = NCDslTermContext(
                 intentMeta = intent.meta,
                 reqMeta = ctx.getRequest.getRequestData,
@@ -564,7 +547,7 @@ object NCIntentSolverEngine extends LazyLogging with NCOpenCensusTrace {
                             logger,
                             Some(
                                 s"Intent '$intentId' ${r("did not")} match because of remaining unused user tokens $varStr." +
-                                s"\nUnused user tokens for intent '$intentId' $varStr:"
+                                    s"\nUnused user tokens for intent '$intentId' $varStr:"
                             )
                         )
                 else {
@@ -589,16 +572,16 @@ object NCIntentSolverEngine extends LazyLogging with NCOpenCensusTrace {
         else
             None
     }
-    
+
     /**
-      * Solves term.
-      *
-      * @param term
-      * @param ctx
-      * @param convToks
-      * @param senToks
-      * @return
-      */
+     * Solves term.
+     *
+     * @param term
+     * @param ctx
+     * @param convToks
+     * @param senToks
+     * @return
+     */
     @throws[NCE]
     private def solveTerm(
         term: NCDslTerm,
@@ -637,21 +620,21 @@ object NCIntentSolverEngine extends LazyLogging with NCOpenCensusTrace {
             // Term not found at all.
             case None ⇒ None
         }
-    
+
     /**
-      * Solves term's predicate.
-      *
-      * @param pred
-      * @param ctx
-      * @param min
-      * @param max
-      * @param senToks
-      * @param convToks
-      * @return
-      */
+     * Solves term's predicate.
+     *
+     * @param pred
+     * @param ctx
+     * @param min
+     * @param max
+     * @param senToks
+     * @param convToks
+     * @return
+     */
     @throws[NCE]
     private def solvePredicate(
-        pred: (NCToken, NCDslTermContext) ⇒ (Boolean/*Predicate.*/, Boolean/*Whether or not token was used.*/),
+        pred: (NCToken, NCDslTermContext) ⇒ (Boolean /*Predicate.*/ , Boolean /*Whether or not token was used.*/ ),
         ctx: NCDslTermContext,
         min: Int,
         max: Int,
@@ -661,23 +644,23 @@ object NCIntentSolverEngine extends LazyLogging with NCOpenCensusTrace {
         // Algorithm is "hungry", i.e. it will fetch all tokens satisfying item's predicate
         // in entire sentence even if these tokens are separated by other already used tokens
         // and conversation will be used only to get to the 'max' number of the item.
-    
+
         var usedToks = List.empty[UsedToken]
-        
+
         var matches = 0
 
         // Collect to the 'max' from sentence & conversation, if possible.
         for (col ← Seq(senToks, convToks); tok ← col.filter(!_.used) if usedToks.lengthCompare(max) < 0) {
             val (res, used) = pred.apply(tok.token, ctx)
-            
+
             if (res) {
                 matches += 1
-    
+
                 if (used)
                     usedToks :+= tok
             }
         }
-    
+
         // We couldn't collect even 'min' matches.
         if (matches < min)
             None
@@ -685,13 +668,13 @@ object NCIntentSolverEngine extends LazyLogging with NCOpenCensusTrace {
         else if (matches == 0) {
             require(min == 0)
             require(usedToks.isEmpty)
-            
+
             Some(usedToks → new Weight(0, 0))
         }
         // We've found some matches (and min > 0).
         else {
             require(matches > 0 && matches > min)
-            
+
             val convSrvReqIds = convToks.map(_.token.getServerRequestId).distinct
 
             // Number of tokens from the current sentence.
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentSolverInput.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/solver/NCIntentSolverInput.scala
similarity index 95%
rename from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentSolverInput.scala
rename to nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/solver/NCIntentSolverInput.scala
index 5f627d1..c8ffb59 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentSolverInput.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/solver/NCIntentSolverInput.scala
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.nlpcraft.model.intent.impl
+package org.apache.nlpcraft.model.intent.solver
 
 import org.apache.nlpcraft.model.{NCContext, NCIntentMatch}
 
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentSolverResult.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/solver/NCIntentSolverResult.scala
similarity index 90%
rename from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentSolverResult.scala
rename to nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/solver/NCIntentSolverResult.scala
index 10ccabb..cf5ea6c 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentSolverResult.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/solver/NCIntentSolverResult.scala
@@ -15,14 +15,14 @@
  * limitations under the License.
  */
 
-package org.apache.nlpcraft.model.intent.impl
+package org.apache.nlpcraft.model.intent.solver
 
 import org.apache.nlpcraft.model.{NCIntentMatch, _}
 
 /**
   * Intent solver engine result. Using basic case class for easier Java interop.
   */
-case class NCIntentTokensGroup(termId: String, tokens: List[NCToken])
+case class NCIntentTokensGroup(termId: Option[String], tokens: List[NCToken])
 case class NCIntentSolverResult(
     intentId: String,
     fn: java.util.function.Function[NCIntentMatch, NCResult],
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentSolverVariant.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/solver/NCIntentSolverVariant.scala
similarity index 66%
rename from nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentSolverVariant.scala
rename to nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/solver/NCIntentSolverVariant.scala
index fd8f86a..e6b7da4 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentSolverVariant.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/solver/NCIntentSolverVariant.scala
@@ -1,37 +1,18 @@
-/*
- * 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.nlpcraft.model.intent.solver
 
-package org.apache.nlpcraft.model.intent.impl
+import org.apache.nlpcraft.model.NCToken
 
 import java.util
 
-import org.apache.nlpcraft.model._
-
-import scala.collection.JavaConverters._
-
 /**
-  * Sentence variant & its weight.
-  */
+ * Sentence variant & its weight.
+ */
 case class NCIntentSolverVariant(tokens: util.List[NCToken]) extends Ordered[NCIntentSolverVariant] {
     val (userToks, wordCnt, avgWordsPerTokPct, totalSparsity, totalUserDirect) = calcWeight()
 
     /**
-      * Calculates weight components.
-      */
+     * Calculates weight components.
+     */
     private def calcWeight(): (Int, Int, Int, Int, Int) = {
         var userToks = 0 // More is better.
         var wordCnt = 0
@@ -87,5 +68,5 @@ case class NCIntentSolverVariant(tokens: util.List[NCToken]) extends Ordered[NCI
             s", avgWordsPerTokPct=$avgWordsPerTokPct" +
             s", sparsity=$totalSparsity" +
             s", toks=$tokens" +
-        "]"
-}
\ No newline at end of file
+            "]"
+}
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/utils/NCDslTokenChecker.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/utils/NCDslTokenChecker.scala
deleted file mode 100644
index 6bfce61..0000000
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/utils/NCDslTokenChecker.scala
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.nlpcraft.model.intent.utils
-
-import org.apache.nlpcraft.model.NCToken
-import org.apache.nlpcraft.common._
-
-import scala.collection.mutable
-
-/**
- * Token checker.
- */
-object NCDslTokenChecker {
-    /**
-     *
-     * @param tok
-     * @param id
-     * @return
-     */
-    def isValidGroup(tok: NCToken, id: String): Boolean =
-        tok.getModel.getMetadata.get(MDL_META_ALL_GRP_IDS_KEY).asInstanceOf[Set[String]].contains(id)
-    
-    /**
-      *
-      * @param tok
-      * @param id
-      * @return
-      */
-    def isValidElementId(tok: NCToken, id: String): Boolean =
-        tok.getModel.getMetadata.get(MDL_META_ALL_ELM_IDS_KEY).asInstanceOf[Set[String]].contains(id)
-}
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/utils/NCDslTokenPredicate.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/utils/NCDslTokenPredicate.java
deleted file mode 100644
index 41e66ae..0000000
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/utils/NCDslTokenPredicate.java
+++ /dev/null
@@ -1,473 +0,0 @@
-/*
- * 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.nlpcraft.model.intent.utils;
-
-import org.apache.commons.collections.*;
-import org.apache.commons.lang3.*;
-import org.apache.nlpcraft.common.util.*;
-import org.apache.nlpcraft.model.*;
-import java.util.*;
-import java.util.function.*;
-import java.util.regex.*;
-import java.util.stream.*;
-
-/**
- * Internal DSL token predicate.
- */
-@SuppressWarnings("unchecked")
-public class NCDslTokenPredicate implements Function<NCToken, Boolean> {
-    private static final List<String> OPS = Arrays.asList(
-        // Order is important!
-        "==",
-        "!=",
-        ">=",
-        "<=",
-        "@@",
-        "!@",
-        ">",
-        "<"
-    );
-
-    private static final List<String> PARAMS = Arrays.asList(
-        "id",
-        "ancestors",
-        "parent",
-        "groups",
-        "value",
-        "aliases",
-        "startidx",
-        "endidx"
-    );
-
-    private final List<String> parts;
-    private final String param;
-    private final String paramFunc;
-    private final String op;
-    private final Object value;
-    private final String valueStr;
-    private final Function<NCToken, NCToken> qualFunc;
-
-    private boolean validated = false;
-
-    /**
-     * Creates new predicate with given parameters.
-     *
-     * @param parts List of qualification token IDs or aliases.
-     * @param paramFunc Optional parameter function. Can be {@code null}.
-     * @param param Rule's left-side parameter.
-     * @param op Rule's operation.
-     * @param value Rule's right-side value.
-     */
-    public NCDslTokenPredicate(List<String> parts, String paramFunc, String param, String op, Object value) {
-        assert parts != null;
-
-        // Assert?
-        if (param == null || (param.charAt(0) != '~' && !PARAMS.contains(param)))
-            throw new IllegalArgumentException(String.format(
-                "Invalid token predicate DSL parameter ('%s'): %s %s %s",
-                param, param, op, value));
-
-        // Assert?
-        if (op == null || !OPS.contains(op))
-            throw new IllegalArgumentException(String.format(
-                "Invalid token predicate DSL operation ('%s'): %s %s %s",
-                op, param, op, value));
-
-        this.parts = new ArrayList<>(parts);
-        this.paramFunc = paramFunc;
-        this.param = param;
-        this.op = op;
-
-        if (value == null)
-            valueStr = "null";
-        else if (value instanceof Collection)
-            valueStr =
-                "(" +
-                ((Collection<?>)value).stream().map(Object::toString).collect(Collectors.joining(",")) +
-                ")";
-        else
-            valueStr = value.toString();
-
-        if (value instanceof String)
-            this.value = stripQuotes((String)value);
-        else if (value instanceof Collection)
-            this.value = ((Collection<?>)value).stream().map(obj -> {
-                if (obj instanceof String) return stripQuotes((String)obj); else return obj;
-            }).collect(Collectors.toList());
-        else
-            this.value = value;
-
-        qualFunc = new NCDslTokenQualifier(this.parts);
-    }
-
-    /**
-     *
-     * @param s
-     * @return
-     */
-    private String stripQuotes(String s) {
-        boolean start = s.charAt(0) == '\'';
-        boolean end = s.charAt(s.length() - 1) == '\'';
-
-        return start && end ? s.substring(1, s.length() - 1) : s;
-    }
-
-    /**
-     *
-     */
-    private IllegalArgumentException operatorError(Object lv, Object rv) {
-        return new IllegalArgumentException(String.format(
-            "Unexpected token predicate DSL operator '%s' for values: %s, %s",
-            op, lv.toString(), rv.toString()));
-    }
-
-    /**
-     *
-     * @param s
-     * @return
-     */
-    private boolean isRegex(String s) {
-        return s.startsWith(NCUtils.REGEX_FIX()) && s.endsWith(NCUtils.REGEX_FIX());
-    }
-
-    /**
-     *
-     * @param s
-     * @return
-     */
-    private String stripRegex(String s) {
-        int len = NCUtils.REGEX_FIX().length();
-
-        return s.substring(len, s.length() - len);
-    }
-
-    /**
-     * 
-     * @param lv Left value.
-     * @param rv right value.
-     * @return
-     */
-    @SuppressWarnings("rawtypes")
-    private boolean doEqual(Object lv, Object rv) {
-        if (lv == rv)
-            return true;
-        // Collection equality.
-        else if (lv instanceof Collection && rv instanceof Collection)
-            return CollectionUtils.isEqualCollection(
-                (Collection)lv,
-                (Collection)rv
-            );
-        // 'in' operator.
-        else if (rv instanceof Collection)
-            return ((Collection)rv).contains(lv);
-        else if (lv instanceof Number && rv instanceof Number)
-            return Double.compare(
-                ((Number)lv).doubleValue(),
-                ((Number)rv).doubleValue()
-            ) == 0;
-        // Regex.
-        else if (lv instanceof String && rv instanceof String && isRegex((String)rv) && !isRegex((String)lv))
-            return Pattern.matches(stripRegex((String)rv), (String)lv);
-        else if (lv instanceof String && rv instanceof String && isRegex((String)lv) && !isRegex((String)rv))
-            return Pattern.matches(stripRegex((String)lv), (String)rv);
-        else if (lv == null || rv == null)
-            return false;
-        else
-            return Objects.equals(lv, rv);
-    }
-
-    /**
-     *
-     * @param lv Left value.
-     * @param rv right value.
-     * @return
-     */
-    @SuppressWarnings("rawtypes")
-    private boolean doContain(Object lv, Object rv) {
-        if (lv == null || lv == rv)
-            return false;
-        else if (lv instanceof Collection && !(rv instanceof Collection))
-            return ((Collection)lv).contains(rv);
-        else if (lv instanceof Collection) // Two collections.
-            return ((Collection)lv).containsAll((Collection)rv);
-        else if (lv instanceof String && rv instanceof String) // Substring containment.
-            return ((String)lv).contains((String)rv);
-        else
-            throw operatorError(lv, rv);
-    }
-
-    /**
-     *
-     * @param v1
-     * @param v2
-     * @return
-     */
-    private int doCompare(Object v1, Object v2) {
-        if (v1 == v2)
-            return 0;
-        else if (v1 == null)
-            return -1;
-        else if (v2 == null)
-            return 1;
-        if (v1 instanceof Number && v2 instanceof Number)
-            return Double.compare(
-                ((Number)v1).doubleValue(),
-                ((Number)v2).doubleValue()
-            );
-        else
-            throw operatorError(v1, v2);
-    }
-
-    /**
-     *
-     * @param lval
-     * @return
-     */
-    private Object processParamFunction(Object lval) {
-        switch (paramFunc) {
-            case "trim":
-                if (lval instanceof String)
-                    return ((String) lval).strip();
-
-                break;
-
-            case "uppercase":
-                if (lval instanceof String)
-                    return ((String) lval).toUpperCase();
-
-                break;
-
-            case "lowercase":
-                if (lval instanceof String)
-                    return ((String) lval).toLowerCase();
-
-                break;
-
-            case "abs":
-                if (lval instanceof Double)
-                    return Math.abs((Double) lval);
-                else if (lval instanceof Float)
-                    return Math.abs((Float) lval);
-                else if (lval instanceof Long)
-                    return Math.abs((Long) lval);
-                else if (lval instanceof Integer)
-                    return Math.abs((Integer) lval);
-
-                break;
-
-            case "ceil":
-                if (lval instanceof Double)
-                    return Math.ceil((Double) lval);
-
-                break;
-
-            case "floor":
-                if (lval instanceof Double)
-                    return Math.floor((Double) lval);
-
-                break;
-
-            case "rint":
-                if (lval instanceof Double)
-                    return Math.rint((Double) lval);
-
-                break;
-
-            case "round":
-                if (lval instanceof Double)
-                    return Math.round((Double) lval);
-                else if (lval instanceof Float)
-                    return Math.round((Float) lval);
-
-                break;
-
-            case "signum":
-                if (lval instanceof Double)
-                    return Math.signum((Double) lval);
-                else if (lval instanceof Float)
-                    return Math.signum((Float) lval);
-
-                break;
-
-            case "keys":
-                if (lval instanceof Map)
-                    return ((Map<String, Object>)lval).keySet();
-
-                break;
-
-            case "values":
-                if (lval instanceof Map)
-                    return ((Map<String, Object>)lval).values();
-
-                break;
-
-            case "isalpha":
-                if (lval instanceof String)
-                    return StringUtils.isAlpha((String) lval);
-
-                break;
-
-            case "isalphanum":
-                if (lval instanceof String)
-                    return StringUtils.isAlphanumeric((String) lval);
-
-                break;
-
-            case "iswhitespace":
-                if (lval instanceof String)
-                    return StringUtils.isWhitespace((String) lval);
-
-                break;
-
-            case "isnumeric":
-                if (lval instanceof String)
-                    return StringUtils.isNumeric((String) lval);
-
-                break;
-
-            case "length":
-            case "count":
-            case "size":
-                if (lval instanceof Collection)
-                    return ((java.util.Collection<Object>)lval).size();
-                else if (lval instanceof Map)
-                    return ((Map<String, Object>)lval).size();
-                else if (lval instanceof String)
-                    return ((String)lval).length();
-
-                break;
-        }
-
-        throw new IllegalArgumentException(String.format("Token predicate function '%s' cannot be applied to value type '%s'",
-            paramFunc, lval.getClass().toString()));
-    }
-
-    @Override
-    public Boolean apply(NCToken tok) {
-        // Qualify token, if required.
-        tok = qualFunc.apply(tok);
-
-        Object lval = null;
-
-        if (param.charAt(0) == '~') {
-            String str = param.substring(1);
-
-            if (str.isEmpty())
-                throw new IllegalArgumentException(String.format("Token predicate DSL empty meta parameter name: %s %s %s",
-                    param, op, valueStr));
-
-            String[] parts = str.split("[\\[\\]]");
-
-            String metaName = parts[0];
-
-            if (parts.length == 1)
-                lval = tok.meta(metaName);
-            else if (parts.length == 2) {
-                Object obj = tok.meta(metaName);
-
-                if (obj != null) {
-                    String strIdx = parts[1];
-
-                    if (strIdx.isEmpty())
-                        throw new IllegalArgumentException(
-                            String.format("Token predicate DSL meta parameter empty index: %s %s %s", param, op,
-                                valueStr));
-                    else if (obj instanceof java.util.List) {
-                        try {
-                            lval = ((List<Object>)obj).get(Integer.parseInt(strIdx));
-                        }
-                        catch (NumberFormatException e) {
-                            throw new IllegalArgumentException(String.format(
-                                "Invalid token predicate DSL meta parameter index ('%s') for java.util.List value (integer only): %s %s %s",
-                                strIdx, param, op, valueStr),
-                                e);
-                        }
-                    }
-                    else if (obj instanceof Map)
-                        lval = ((Map<String, Object>)obj).get(stripQuotes(strIdx));
-                    else
-                        throw new IllegalArgumentException(String.format(
-                            "Invalid token predicate DSL meta parameter value " +
-                            "for indexed access (java.util.List or java.util.Map only): %s %s %s",
-                            param, op, valueStr));
-                }
-            }
-            else
-                throw new IllegalArgumentException(String.format(
-                    "Invalid token predicate DSL meta parameter: %s %s %s", param, op, valueStr));
-        }
-        else
-            switch (param) {
-                case "id": lval = tok.getId().strip(); break;
-                case "groups": lval = tok.getGroups(); break;
-                case "aliases": lval = tok.getAliases(); break;
-                case "startidx": lval = tok.getStartCharIndex(); break;
-                case "endidx": lval = tok.getEndCharIndex(); break;
-                case "ancestors": lval = tok.getAncestors(); break;
-                case "value": lval = tok.getValue() == null ? null : tok.getValue().strip(); break;
-                case "parent": lval = tok.getParentId() == null ? null : tok.getParentId().strip(); break;
-
-                default: throw new IllegalArgumentException(String.format(
-                    "Invalid token predicate DSL parameter ('%s'): %s %s %s",
-                    param, param, op, valueStr));
-            }
-
-        if (paramFunc != null)
-            lval = processParamFunction(lval);
-
-        Object rval = value;
-
-        if (!validated) {
-            if ((param.equals("ancestors") ||
-                param.equals("id") ||
-                param.equals("parent")) &&
-                !NCDslTokenChecker.isValidElementId(tok, (String)rval))
-                throw new IllegalArgumentException(String.format("Attempt to check unknown element ID '%s': %s %s %s",
-                    rval, param, op, valueStr));
-
-            if ((param.equals("groups")) &&
-                !NCDslTokenChecker.isValidGroup(tok, (String)rval))
-                throw new IllegalArgumentException(String.format("Attempt to check unknown group ID '%s': %s %s %s",
-                    rval, param, op, valueStr));
-
-            validated = true;
-        }
-
-        switch (op) {
-            case "==": return doEqual(lval, rval);
-            case "!=": return !doEqual(lval, rval);
-            case ">": return doCompare(lval, rval) == 1;
-            case ">=": return doCompare(lval, rval) >= 0;
-            case "<": return doCompare(lval, rval) == -1;
-            case "<=": return doCompare(lval, rval) <= 0;
-            case "@@": return doContain(lval, rval);
-            case "!@": return !doContain(lval, rval);
-
-            default:
-                throw new AssertionError("Unexpected token predicate DSL operation: " + op);
-        }
-    }
-
-    @Override
-    public String toString() {
-        String x = parts.isEmpty() ? param : String.format("%s.%s", String.join(".", parts), param);
-        String x1 = paramFunc != null ? String.format("%s(%s)", paramFunc, x) : x;
-
-        return String.format("%s %s %s", x1, op, valueStr);
-    }
-}
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/utils/NCDslTokenQualifier.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/utils/NCDslTokenQualifier.scala
deleted file mode 100644
index fe5d6e0..0000000
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/utils/NCDslTokenQualifier.scala
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.nlpcraft.model.intent.utils
-
-import org.apache.nlpcraft.common._
-import org.apache.nlpcraft.model.NCToken
-
-import scala.collection.JavaConverters._
-import scala.collection.mutable
-
-/**
- * DSL token qualifier.
- */
-class NCDslTokenQualifier(parts: java.util.List[String]) extends java.util.function.Function[NCToken, NCToken] {
-    private final val func: NCToken ⇒ NCToken =
-        if (parts.isEmpty)
-            t ⇒ t // Identity function.
-        else
-            t ⇒ {
-                var tok = t
-                
-                for (part ← parts.asScala) {
-                    val partToks = tok.getPartTokens.asScala
-                    
-                    val qualToks: mutable.Buffer[(NCToken, Set[String]/*ID or predicate alias*/)] =
-                        (
-                            partToks.zip(partToks.map(tok ⇒ Set(tok.getId))) ++
-                            partToks.zip(partToks.map(tok ⇒ tok.meta(TOK_META_ALIASES_KEY).asInstanceOf[java.util.Set[String]] match {
-                                case null ⇒ Set.empty[String]
-                                case x ⇒ x.asScala.toSet
-                            }))
-                        )
-                        .filter(_._2.contains(part))
-                    
-                    if (qualToks.isEmpty)
-                        throw new IllegalArgumentException(s"Unknown part token qualifier: $part for token: ${t.getId}")
-                    if (qualToks.size > 1)
-                        throw new IllegalArgumentException(s"Multiple part tokens found for: $part for token: ${t.getId}")
-                    
-                    tok = qualToks.head._1
-                }
-                
-                tok
-            }
-        
-    override def apply(tok: NCToken): NCToken = func(tok)
-}
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeModel.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeModel.scala
index f52d8d2..bc2cd72 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeModel.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeModel.scala
@@ -17,7 +17,7 @@
 
 package org.apache.nlpcraft.probe.mgrs
 
-import org.apache.nlpcraft.model.intent.impl.NCIntentSolver
+import org.apache.nlpcraft.model.intent.solver.NCIntentSolver
 import org.apache.nlpcraft.model.intent.utils.NCDslIntent
 import org.apache.nlpcraft.model.{NCElement, NCModel}
 
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/deploy/NCDeployManager.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/deploy/NCDeployManager.scala
index e63aceb..6e3ddb4 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/deploy/NCDeployManager.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/deploy/NCDeployManager.scala
@@ -33,7 +33,8 @@ import org.apache.nlpcraft.common.nlp.core.{NCNlpCoreManager, NCNlpPorterStemmer
 import org.apache.nlpcraft.common.util.NCUtils.{DSL_FIX, REGEX_FIX}
 import org.apache.nlpcraft.model._
 import org.apache.nlpcraft.model.factories.basic.NCBasicModelFactory
-import org.apache.nlpcraft.model.intent.impl.{NCIntentDslCompiler, NCIntentSolver}
+import org.apache.nlpcraft.model.intent.compiler.NCIntentDslCompiler
+import org.apache.nlpcraft.model.intent.solver.NCIntentSolver
 import org.apache.nlpcraft.model.intent.utils.NCDslIntent
 import org.apache.nlpcraft.probe.mgrs.NCProbeSynonymChunkKind.{DSL, REGEX, TEXT}
 import org.apache.nlpcraft.probe.mgrs.{NCProbeModel, NCProbeSynonym, NCProbeSynonymChunk, NCProbeSynonymsWrapper}
@@ -466,7 +467,6 @@ object NCDeployManager extends NCService with DecorateAsScala {
                 throw new NCE(s"Duplicated synonyms found and not allowed [mdlId=$mdlId]")
         }
 
-        mdl.getMetadata.put(MDL_META_ALL_ALIASES_KEY, allAliases.toSet)
         mdl.getMetadata.put(MDL_META_ALL_ELM_IDS_KEY,
             mdl.getElements.asScala.map(_.getId).toSet ++
                 Set("nlpcraft:nlp") ++
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/dialogflow/NCDialogFlowManager.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/dialogflow/NCDialogFlowManager.scala
index cec9bdd..aeb931f 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/dialogflow/NCDialogFlowManager.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/dialogflow/NCDialogFlowManager.scala
@@ -19,8 +19,8 @@ package org.apache.nlpcraft.probe.mgrs.dialogflow
 
 import io.opencensus.trace.Span
 import org.apache.nlpcraft.common.{NCService, _}
+import org.apache.nlpcraft.model.intent.solver.NCIntentSolverResult
 import org.apache.nlpcraft.model.{NCContext, NCDialogFlowItem, NCIntentMatch}
-import org.apache.nlpcraft.model.intent.impl.NCIntentSolverResult
 import org.apache.nlpcraft.probe.mgrs.model.NCModelManager
 
 import scala.collection._
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCProbeEnrichmentManager.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCProbeEnrichmentManager.scala
index 9aec9cc..da85340 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCProbeEnrichmentManager.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCProbeEnrichmentManager.scala
@@ -27,7 +27,7 @@ import org.apache.nlpcraft.common.nlp.{NCNlpSentence, NCNlpSentenceNote}
 import org.apache.nlpcraft.common.pool.NCThreadPoolManager
 import org.apache.nlpcraft.model._
 import org.apache.nlpcraft.model.impl.NCTokenLogger
-import org.apache.nlpcraft.model.intent.impl.NCIntentSolverInput
+import org.apache.nlpcraft.model.intent.solver.NCIntentSolverInput
 import org.apache.nlpcraft.model.opencensus.stats.NCOpenCensusModelStats
 import org.apache.nlpcraft.model.tools.embedded.NCEmbeddedResult
 import org.apache.nlpcraft.probe.mgrs.conn.NCConnectionManager
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/dsl/compiler/NCIntentDslCompilerSpec.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/dsl/compiler/NCIntentDslCompilerSpec.scala
index 685ea43..761f5e3 100644
--- a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/dsl/compiler/NCIntentDslCompilerSpec.scala
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/dsl/compiler/NCIntentDslCompilerSpec.scala
@@ -18,7 +18,8 @@
 package org.apache.nlpcraft.model.intent.dsl.compiler
 
 import org.apache.nlpcraft.common._
-import org.apache.nlpcraft.model.intent.impl.{NCIntentDslCompiler, NCIntentDslFragmentCache}
+import org.apache.nlpcraft.model.intent.compiler.{NCIntentDslCompiler, NCIntentDslFragmentCache}
+import org.apache.nlpcraft.model.intent.impl.NCIntentDslFragmentCache
 import org.junit.jupiter.api.Test
 
 import java.nio.file.{Path, Paths}


[incubator-nlpcraft] 01/02: WIP.

Posted by ar...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

aradzinski pushed a commit to branch NLPCRAFT-206
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git

commit 67255ef6c46eea3a6791fed18c3b5f6c333d769a
Author: Aaron Radzinski <ar...@apache.org>
AuthorDate: Mon Mar 8 16:42:01 2021 -0800

    WIP.
---
 .../intent/impl/NCIntentDslBaselCompiler.scala     | 171 +++++-----------
 .../model/intent/impl/NCIntentDslCompiler.scala    | 224 ++++++++++++++-------
 .../probe/mgrs/deploy/NCDeployManager.scala        |   6 +-
 .../dsl/compiler/NCIntentDslCompilerSpec.scala     |   6 +-
 4 files changed, 209 insertions(+), 198 deletions(-)

diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslBaselCompiler.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslBaselCompiler.scala
index 0011b26..f31286e 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslBaselCompiler.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslBaselCompiler.scala
@@ -419,20 +419,6 @@ trait NCIntentDslBaselCompiler {
             pop1()
         }
 
-        /*
-         * String operations.
-         */
-        def doTrim(): Unit = get1Str() match { case (s, f) ⇒ pushAny(s.trim, f) }
-        def doUppercase(): Unit = get1Str() match { case (s, f) ⇒ pushAny(s.toUpperCase, f) }
-        def doLowercase(): Unit = get1Str() match { case (s, f) ⇒ pushAny(s.toLowerCase, f) }
-        def doIsAlpha(): Unit = get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlpha(asString(s)), f) }
-        def doIsNum(): Unit = get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isNumeric(asString(s)), f) }
-        def doIsAlphaNum(): Unit = get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlphanumeric(asString(s)), f) }
-        def doIsWhitespace(): Unit = get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isWhitespace(asString(s)), f) }
-        def doIsAlphaSpace(): Unit = get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlphaSpace(asString(s)), f) }
-        def doIsAlphaNumSpace(): Unit = get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlphanumericSpace(asString(s)), f) }
-        def doIsNumSpace(): Unit = get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isNumericSpace(asString(s)), f) }
-
         def doSplit(): Unit = {
             ensureStack(2)
 
@@ -502,15 +488,6 @@ trait NCIntentDslBaselCompiler {
         /*
          * Metadata operations.
          */
-        def doTokenMeta(): Unit = get1Str() match { case (s, _) ⇒ pushAny(tok.meta(s), true) }
-        def doModelMeta(): Unit = get1Str() match { case (s, _) ⇒ pushAny(tok.getModel.meta(s), false) }
-        def doReqMeta(): Unit = get1Str() match { case (s, _) ⇒ pushAny(termCtx.reqMeta.get(s).orNull, false) }
-        def doSysMeta(): Unit = get1Str() match { case (s, _) ⇒ pushAny(U.sysEnv(s).orNull, false) }
-        def doUserMeta(): Unit = get1Str() match { case (s, _) ⇒ pushAny(termCtx.usrMeta.get(s).orNull, false) }
-        def doConvMeta(): Unit = get1Str() match { case (s, _) ⇒ pushAny(termCtx.convMeta.get(s).orNull, false) }
-        def doCompMeta(): Unit = get1Str() match { case (s, _) ⇒ pushAny(termCtx.compMeta.get(s).orNull, false) }
-        def doIntentMeta(): Unit = get1Str() match { case (s, _) ⇒ pushAny(termCtx.intentMeta.get(s).orNull, false) }
-        def doFragMeta(): Unit = get1Str() match { case (s, _) ⇒ pushAny(termCtx.fragMeta.get(s).orNull, false) }
         def doPartMeta(): Unit = {
             ensureStack(2)
 
@@ -537,44 +514,6 @@ trait NCIntentDslBaselCompiler {
             case (a: JDouble, f) ⇒ pushDouble(a * a, f)
             case x ⇒ throw rtParamTypeError(fun, x, "numeric")
         }
-        def doCeil(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.ceil(a), f) }
-        def doFloor(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.floor(a), f) }
-        def doSignum(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.signum(a), f) }
-        def doAcos(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.acos(a), f) }
-        def doAsin(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.asin(a), f) }
-        def doSin(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.sin(a), f) }
-        def doCos(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.cos(a), f) }
-        def doRint(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.rint(a), f) }
-        def doRound(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushLong(Math.round(a), f) }
-        def doSqrt(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.sqrt(a), f) }
-        def doCbrt(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.cbrt(a), f) }
-        def doAtan(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.atan(a), f) }
-        def doTan(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.tan(a), f) }
-        def doCosh(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.cosh(a), f) }
-        def doSinh(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.sinh(a), f) }
-        def doTanh(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.tanh(a), f) }
-        def doLog(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.log(a), f) }
-        def doLog1p(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.log1p(a), f) }
-        def doLog10(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.log10(a), f) }
-        def doDegrees(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.toDegrees(a), f) }
-        def doRadians(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.toRadians(a), f) }
-        def doExp(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.exp(a), f) }
-        def doExpm1(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.expm1(a), f) }
-        def doRandom(): Unit = pushDouble(Math.random, false)
-        def doPi(): Unit = pushDouble(Math.PI, false)
-        def doEuler(): Unit = pushDouble(Math.E, false)
-        def doPow(): Unit = get2Doubles() match { case (a1: JDouble, a2: JDouble, f) ⇒ pushDouble(Math.pow(a1, a2), f) }
-        def doHypot(): Unit = get2Doubles() match { case (a1: JDouble, a2: JDouble, f) ⇒ pushDouble(Math.hypot(a1, a2), f) }
-        def doAtan2(): Unit = get2Doubles() match { case (a1: JDouble, a2: JDouble, f) ⇒ pushDouble(Math.atan2(a1, a2), f) }
-
-        /*
-         * Date-time operations.
-         */
-        def doYear(): Unit = pushLong(LocalDate.now.getYear,false)
-        def doMonth(): Unit = pushLong(LocalDate.now.getMonthValue,false)
-        def doDayOfMonth(): Unit = pushLong(LocalDate.now.getDayOfMonth,false)
-        def doDayOfWeek(): Unit = pushLong(LocalDate.now.getDayOfWeek.getValue,false)
-        def doDayOfYear(): Unit = pushLong(LocalDate.now.getDayOfYear,false)
 
         def doJson(): Unit = get1Str() match { case (s, f) ⇒ pushAny(U.jsonToJavaMap(asString(s)), f) }
         def doIf(): Unit = {
@@ -638,16 +577,16 @@ trait NCIntentDslBaselCompiler {
 
         fun match {
             // Metadata access.
-            case "meta_token" ⇒ doTokenMeta()
             case "meta_part" ⇒ doPartMeta()
-            case "meta_model" ⇒ doModelMeta()
-            case "meta_intent" ⇒ doIntentMeta()
-            case "meta_req" ⇒ doReqMeta()
-            case "meta_user" ⇒ doUserMeta()
-            case "meta_company" ⇒ doCompMeta()
-            case "meta_sys" ⇒ doSysMeta()
-            case "meta_conv" ⇒ doConvMeta()
-            case "meta_frag" ⇒ doFragMeta()
+            case "meta_token" ⇒ get1Str() match { case (s, _) ⇒ pushAny(tok.meta(s), true) }
+            case "meta_model" ⇒ get1Str() match { case (s, _) ⇒ pushAny(tok.getModel.meta(s), false) }
+            case "meta_intent" ⇒ get1Str() match { case (s, _) ⇒ pushAny(termCtx.intentMeta.get(s).orNull, false) }
+            case "meta_req" ⇒ get1Str() match { case (s, _) ⇒ pushAny(termCtx.reqMeta.get(s).orNull, false) }
+            case "meta_user" ⇒ get1Str() match { case (s, _) ⇒ pushAny(termCtx.usrMeta.get(s).orNull, false) }
+            case "meta_company" ⇒ get1Str() match { case (s, _) ⇒ pushAny(termCtx.compMeta.get(s).orNull, false) }
+            case "meta_sys" ⇒ get1Str() match { case (s, _) ⇒ pushAny(U.sysEnv(s).orNull, false) }
+            case "meta_conv" ⇒ get1Str() match { case (s, _) ⇒ pushAny(termCtx.convMeta.get(s).orNull, false) }
+            case "meta_frag" ⇒ get1Str() match { case (s, _) ⇒ pushAny(termCtx.fragMeta.get(s).orNull, false) }
 
             // Converts JSON to map.
             case "json" ⇒ doJson()
@@ -694,17 +633,17 @@ trait NCIntentDslBaselCompiler {
             case "comp_postcode" ⇒
 
             // String functions.
-            case "trim" ⇒ doTrim()
-            case "strip" ⇒ doTrim()
-            case "uppercase" ⇒ doUppercase()
-            case "lowercase" ⇒ doLowercase()
-            case "is_alpha" ⇒ doIsAlpha()
-            case "is_alphanum" ⇒ doIsAlphaNum()
-            case "is_whitespace" ⇒ doIsWhitespace()
-            case "is_num" ⇒ doIsNum()
-            case "is_numspace" ⇒ doIsNumSpace()
-            case "is_alphaspace" ⇒ doIsAlphaSpace()
-            case "is_alphanumspace" ⇒ doIsAlphaNumSpace()
+            case "trim" ⇒ get1Str() match { case (s, f) ⇒ pushAny(s.trim, f) }
+            case "strip" ⇒ get1Str() match { case (s, f) ⇒ pushAny(s.trim, f) }
+            case "uppercase" ⇒ get1Str() match { case (s, f) ⇒ pushAny(s.toUpperCase, f) }
+            case "lowercase" ⇒ get1Str() match { case (s, f) ⇒ pushAny(s.toLowerCase, f) }
+            case "is_alpha" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlpha(asString(s)), f) }
+            case "is_alphanum" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlphanumeric(asString(s)), f) }
+            case "is_whitespace" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isWhitespace(asString(s)), f) }
+            case "is_num" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isNumeric(asString(s)), f) }
+            case "is_numspace" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isNumericSpace(asString(s)), f) }
+            case "is_alphaspace" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlphaSpace(asString(s)), f) }
+            case "is_alphanumspace" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlphanumericSpace(asString(s)), f) }
             case "substring" ⇒
             case "charAt" ⇒
             case "regex" ⇒
@@ -715,35 +654,35 @@ trait NCIntentDslBaselCompiler {
 
             // Math functions.
             case "abs" ⇒ doAbs()
-            case "ceil" ⇒ doCeil()
-            case "floor" ⇒ doFloor()
-            case "rint" ⇒ doRint()
-            case "round" ⇒ doRound()
-            case "signum" ⇒ doSignum()
-            case "sqrt" ⇒ doSqrt()
-            case "cbrt" ⇒ doCbrt()
-            case "pi" ⇒ doPi()
-            case "euler" ⇒ doEuler()
-            case "acos" ⇒ doAcos()
-            case "asin" ⇒ doAsin()
-            case "atan" ⇒ doAtan()
-            case "cos" ⇒ doCos()
-            case "sin" ⇒ doSin()
-            case "tan" ⇒ doTan()
-            case "cosh" ⇒ doCosh()
-            case "sinh" ⇒ doSinh()
-            case "tanh" ⇒ doTanh()
-            case "atn2" ⇒ doAtan2()
-            case "degrees" ⇒ doDegrees()
-            case "radians" ⇒ doRadians()
-            case "exp" ⇒ doExp()
-            case "expm1" ⇒ doExpm1()
-            case "hypot" ⇒ doHypot()
-            case "log" ⇒ doLog()
-            case "log10" ⇒ doLog10()
-            case "log1p" ⇒ doLog1p()
-            case "pow" ⇒ doPow()
-            case "rand" ⇒ doRandom()
+            case "ceil" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.ceil(a), f) }
+            case "floor" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.floor(a), f) }
+            case "rint" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.rint(a), f) }
+            case "round" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushLong(Math.round(a), f) }
+            case "signum" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.signum(a), f) }
+            case "sqrt" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.sqrt(a), f) }
+            case "cbrt" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.cbrt(a), f) }
+            case "pi" ⇒ pushDouble(Math.PI, false)
+            case "euler" ⇒ pushDouble(Math.E, false)
+            case "acos" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.acos(a), f) }
+            case "asin" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.asin(a), f) }
+            case "atan" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.atan(a), f) }
+            case "cos" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.cos(a), f) }
+            case "sin" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.sin(a), f) }
+            case "tan" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.tan(a), f) }
+            case "cosh" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.cosh(a), f) }
+            case "sinh" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.sinh(a), f) }
+            case "tanh" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.tanh(a), f) }
+            case "atn2" ⇒ get2Doubles() match { case (a1: JDouble, a2: JDouble, f) ⇒ pushDouble(Math.atan2(a1, a2), f) }
+            case "degrees" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.toDegrees(a), f) }
+            case "radians" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.toRadians(a), f) }
+            case "exp" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.exp(a), f) }
+            case "expm1" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.expm1(a), f) }
+            case "hypot" ⇒ get2Doubles() match { case (a1: JDouble, a2: JDouble, f) ⇒ pushDouble(Math.hypot(a1, a2), f) }
+            case "log" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.log(a), f) }
+            case "log10" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.log10(a), f) }
+            case "log1p" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.log1p(a), f) }
+            case "pow" ⇒ get2Doubles() match { case (a1: JDouble, a2: JDouble, f) ⇒ pushDouble(Math.pow(a1, a2), f) }
+            case "rand" ⇒ pushDouble(Math.random, false)
             case "square" ⇒ doSquare()
 
             // Collection functions.
@@ -777,18 +716,18 @@ trait NCIntentDslBaselCompiler {
             case "sum" ⇒
 
             // Date-time functions.
-            case "year" ⇒ doYear() // 2021.
-            case "month" ⇒ doMonth() // 1 ... 12.
-            case "day_of_month" ⇒ doDayOfMonth() // 1 ... 31.
-            case "day_of_week" ⇒ doDayOfWeek()
-            case "day_of_year" ⇒ doDayOfYear()
+            case "year" ⇒ pushLong(LocalDate.now.getYear,false) // 2021.
+            case "month" ⇒ pushLong(LocalDate.now.getMonthValue,false) // 1 ... 12.
+            case "day_of_month" ⇒ pushLong(LocalDate.now.getDayOfMonth,false) // 1 ... 31.
+            case "day_of_week" ⇒ pushLong(LocalDate.now.getDayOfWeek.getValue,false)
+            case "day_of_year" ⇒ pushLong(LocalDate.now.getDayOfYear,false)
             case "hour" ⇒
             case "minute" ⇒
             case "second" ⇒
             case "week_of_month" ⇒
             case "week_of_year" ⇒
             case "quarter" ⇒
-            case "now" ⇒ // Epoc time.
+            case "now" ⇒ pushLong(System.currentTimeMillis(),false) // Epoc time.
 
             case _ ⇒ throw rtUnknownFunError(fun) // Assertion.
         }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslCompiler.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslCompiler.scala
index 1fdbd57..691af29 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslCompiler.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslCompiler.scala
@@ -34,8 +34,9 @@ import scala.collection.mutable
 import scala.collection.mutable.ArrayBuffer
 
 object NCIntentDslCompiler extends LazyLogging {
-    // Compiler cache.
-    private val cache = new mutable.HashMap[String, Set[NCDslIntent]]
+    // Compiler caches.
+    private val intentCache = new mutable.HashMap[String, Set[NCDslIntent]]
+    private val synCache = new mutable.HashMap[String, NCDslSynonym]
 
     /**
      *
@@ -76,12 +77,19 @@ object NCIntentDslCompiler extends LazyLogging {
          * Shared/common implementation.
          */
         override def exitUnaryExpr(ctx: IDP.UnaryExprContext): Unit = termInstrs += parseUnaryExpr(ctx.MINUS(), ctx.NOT())(ctx)
+
         override def exitMultExpr(ctx: IDP.MultExprContext): Unit = termInstrs += parseMultExpr(ctx.MULT(), ctx.MOD(), ctx.DIV())(ctx)
+
         override def exitPlusExpr(ctx: IDP.PlusExprContext): Unit = termInstrs += parsePlusExpr(ctx.PLUS(), ctx.MINUS())(ctx)
+
         override def exitCompExpr(ctx: IDP.CompExprContext): Unit = termInstrs += parseCompExpr(ctx.LT(), ctx.GT(), ctx.LTEQ(), ctx.GTEQ())(ctx)
+
         override def exitLogExpr(ctx: IDP.LogExprContext): Unit = termInstrs += parseLogExpr(ctx.AND, ctx.OR())(ctx)
+
         override def exitEqExpr(ctx: IDP.EqExprContext): Unit = termInstrs += parseEqExpr(ctx.EQ, ctx.NEQ())(ctx)
+
         override def exitCallExpr(ctx: IDP.CallExprContext): Unit = termInstrs += parseCallExpr(ctx.FUN_NAME())(ctx)
+
         override def exitAtom(ctx: IDP.AtomContext): Unit = termInstrs += parseAtom(ctx.getText)(ctx)
 
         /**
@@ -104,11 +112,11 @@ object NCIntentDslCompiler extends LazyLogging {
             else
                 assert(false)
         }
-    
+
         override def exitMinMaxRange(ctx: IDP.MinMaxRangeContext): Unit = {
             val minStr = ctx.getChild(1).getText.trim
             val maxStr = ctx.getChild(3).getText.trim
-        
+
             try
                 setMinMax(java.lang.Integer.parseInt(minStr), java.lang.Integer.parseInt(maxStr))
             catch {
@@ -126,28 +134,31 @@ object NCIntentDslCompiler extends LazyLogging {
 
         override def exitTermId(ctx: IDP.TermIdContext): Unit = {
             termId = ctx.id().getText
-    
+
             if (terms.exists(t ⇒ t.id === termId))
-                throw newSyntaxError(s"Duplicate term ID: $termId")(ctx.id())
+                throw newSyntaxError(s"Duplicate intent term ID: $termId")(ctx.id())
         }
-    
+
         override def exitIntentId(ctx: IDP.IntentIdContext): Unit = {
             intentId = ctx.id().getText
-    
+
             if (intents.exists(i ⇒ i.id != null && i.id == intentId))
                 throw newSyntaxError(s"Duplicate intent ID: $intentId")(ctx.id())
         }
-    
+
         override def exitFragId(ctx: IDP.FragIdContext): Unit = {
             fragId = ctx.id().getText
-    
+
             if (FragCache.get(mdlId, fragId).isDefined)
                 throw newSyntaxError(s"Duplicate fragment ID: $fragId")(ctx.id())
         }
 
-        override def exitTermEq(ctx: IDP.TermEqContext): Unit =  termConv = ctx.TILDA() != null
+        override def exitTermEq(ctx: IDP.TermEqContext): Unit = termConv = ctx.TILDA() != null
+
         override def exitFragMeta(ctx: IDP.FragMetaContext): Unit = fragMeta = U.jsonToScalaMap(ctx.jsonObj().getText)
+
         override def exitMetaDecl(ctx: IDP.MetaDeclContext): Unit = intentMeta = U.jsonToScalaMap(ctx.jsonObj().getText)
+
         override def exitOrderedDecl(ctx: IDP.OrderedDeclContext): Unit = ordered = ctx.BOOL().getText == "true"
 
         override def exitFragRef(ctx: IDP.FragRefContext): Unit = {
@@ -158,7 +169,7 @@ object NCIntentDslCompiler extends LazyLogging {
                     val meta = if (fragMeta == null) Map.empty[String, Any] else fragMeta
 
                     for (fragTerm ← frag.terms)
-                         if (terms.exists(t ⇒ t.id === fragTerm.id))
+                        if (terms.exists(t ⇒ t.id === fragTerm.id))
                             throw newSyntaxError(s"Duplicate term ID '${fragTerm.id.get}' in fragment '$id'.")(ctx.id())
                         else
                             terms += fragTerm.cloneWithFragMeta(meta)
@@ -261,7 +272,7 @@ object NCIntentDslCompiler extends LazyLogging {
                         val stack = new mutable.ArrayStack[NCDslTermRetVal]()
 
                         // Execute all instructions.
-                        instrs.foreach(_(tok, stack, termCtx))
+                        instrs.foreach(_ (tok, stack, termCtx))
 
                         // Pop final result from stack.
                         val x = stack.pop()
@@ -273,7 +284,7 @@ object NCIntentDslCompiler extends LazyLogging {
                     }
 
                 }
-                
+
             // Add term.
             terms += NCDslTerm(
                 Option(termId),
@@ -296,7 +307,7 @@ object NCIntentDslCompiler extends LazyLogging {
 
             terms.clear()
         }
-        
+
         override def exitIntent(ctx: IDP.IntentContext): Unit = {
             intents += NCDslIntent(
                 dsl,
@@ -319,10 +330,17 @@ object NCIntentDslCompiler extends LazyLogging {
          *
          * @return
          */
-        def getBuiltIntents: Set[NCDslIntent] = intents.toSet
-        
+        def getCompiledIntents: Set[NCDslIntent] = intents.toSet
+
+        /**
+         *
+         * @return
+         */
+        def getCompiledSynonym: NCDslSynonym = ???
+
         override def syntaxError(errMsg: String, srcName: String, line: Int, pos: Int): NCE =
             throw new NCE(mkSyntaxError(errMsg, srcName, line, pos, dsl, mdlId))
+
         override def runtimeError(errMsg: String, srcName: String, line: Int, pos: Int, cause: Exception = null): NCE =
             throw new NCE(mkRuntimeError(errMsg, srcName, line, pos, dsl, mdlId), cause)
     }
@@ -345,15 +363,15 @@ object NCIntentDslCompiler extends LazyLogging {
         mdlId: String): String = mkError("syntax", msg, srcName, line, charPos, dsl, mdlId)
 
     /**
-      *
-      * @param msg
-      * @param dsl
-      * @param mdlId
-      * @param srcName
-      * @param line
-      * @param charPos
-      * @return
-      */
+     *
+     * @param msg
+     * @param dsl
+     * @param mdlId
+     * @param srcName
+     * @param line
+     * @param charPos
+     * @return
+     */
     private def mkRuntimeError(
         msg: String,
         srcName: String,
@@ -379,13 +397,13 @@ object NCIntentDslCompiler extends LazyLogging {
             case s: String if s.last == '.' ⇒ s
             case s: String ⇒ s + '.'
         }
-        
-        s"Intent DSL $kind error in '$srcName' at line $line:${charPos + 1} - $aMsg\n" +
-        s"  |-- ${c("Model:")}    $mdlId\n" +
-        s"  |-- ${c("Line:")}     $dslPtr\n" +
-        s"  +-- ${c("Position:")} $posPtr"
+
+        s"DSL $kind error in '$srcName' at line $line:${charPos + 1} - $aMsg\n" +
+            s"  |-- ${c("Model:")}    $mdlId\n" +
+            s"  |-- ${c("Line:")}     $dslPtr\n" +
+            s"  +-- ${c("Position:")} $posPtr"
     }
-    
+
     /**
      * Custom error handler.
      *
@@ -411,15 +429,15 @@ object NCIntentDslCompiler extends LazyLogging {
             e: RecognitionException): Unit =
             throw new NCE(mkSyntaxError(msg, recog.getInputStream.getSourceName, line, charPos - 1, dsl, mdlId))
     }
-    
+
     /**
-      *
-      * @param dsl
-      * @param mdlId
-      * @param srcName
-      * @return
-      */
-    private def antlr4(
+     *
+     * @param dsl
+     * @param mdlId
+     * @param srcName
+     * @return
+     */
+    private def parseIntents(
         dsl: String,
         mdlId: String,
         srcName: String
@@ -427,61 +445,115 @@ object NCIntentDslCompiler extends LazyLogging {
         require(dsl != null)
         require(mdlId != null)
         require(srcName != null)
-    
-        val aDsl = dsl.strip()
-    
-        val intents: Set[NCDslIntent] = cache.getOrElseUpdate(aDsl, {
-            // ANTLR4 armature.
-            val lexer = new NCIntentDslLexer(CharStreams.fromString(aDsl, srcName))
-            val tokens = new CommonTokenStream(lexer)
-            val parser = new IDP(tokens)
-        
-            // Set custom error handlers.
-            lexer.removeErrorListeners()
-            parser.removeErrorListeners()
-            lexer.addErrorListener(new CompilerErrorListener(aDsl, mdlId))
-            parser.addErrorListener(new CompilerErrorListener(aDsl, mdlId))
-        
-            // State automata.
-            val fsm = new FiniteStateMachine(aDsl, mdlId)
-        
+
+        val x = dsl.strip()
+
+        val intents: Set[NCDslIntent] = intentCache.getOrElseUpdate(x, {
+            val (fsm, parser) = antlr4Armature(x, mdlId)
+
             // Parse the input DSL and walk built AST.
             (new ParseTreeWalker).walk(fsm, parser.dsl())
-        
-            // Return the built intent.
-            fsm.getBuiltIntents
+
+            // Return the compiled intents.
+            fsm.getCompiledIntents
         })
-    
+
         intents
     }
-    
+
     /**
-      * Compiles inline (supplied) fragments and/or intents from given file. Note that fragments are
-      * accumulated in a static map keyed by model ID. Only intents are returned, if any.
-      *
-      * @param filePath *.nc DSL file to compile.
-      * @param mdlId ID of the model *.nc file belongs to.
-      * @return
-      */
+     *
+     * @param dsl
+     * @param mdlId
+     * @return
+     */
+    private def parseSynonym(
+        dsl: String,
+        mdlId: String
+    ): NCDslSynonym = {
+        require(dsl != null)
+        require(mdlId != null)
+
+        val x = dsl.strip()
+
+        val syn: NCDslSynonym = synCache.getOrElseUpdate(x, {
+            val (fsm, parser) = antlr4Armature(x, mdlId)
+
+            // Parse the input DSL and walk built AST.
+            (new ParseTreeWalker).walk(fsm, parser.synonym())
+
+            // Return the compiled synonym.
+            fsm.getCompiledSynonym
+        })
+
+        syn
+    }
+
+    /**
+     *
+     * @param dsl
+     * @param mdlId
+     * @param srcName
+     * @return
+     */
+    private def antlr4Armature(
+        dsl: String,
+        mdlId: String,
+        srcName: String = "<inline>"
+    ): (FiniteStateMachine, IDP) = {
+        val lexer = new NCIntentDslLexer(CharStreams.fromString(dsl, srcName))
+        val tokens = new CommonTokenStream(lexer)
+        val parser = new IDP(tokens)
+
+        // Set custom error handlers.
+        lexer.removeErrorListeners()
+        parser.removeErrorListeners()
+        lexer.addErrorListener(new CompilerErrorListener(dsl, mdlId))
+        parser.addErrorListener(new CompilerErrorListener(dsl, mdlId))
+
+        // State automata + it's parser.
+        new FiniteStateMachine(dsl, mdlId) → parser
+    }
+
+    /**
+     * Compiles inline (supplied) fragments and/or intents from given file. Note that fragments are
+     * accumulated in a static map keyed by model ID. Only intents are returned, if any.
+     *
+     * @param filePath *.nc intent DSL file to compile.
+     * @param mdlId ID of the model *.nc file belongs to.
+     * @return
+     */
     @throws[NCE]
-    def compileIntent(
+    def compileIntents(
         filePath: Path,
         mdlId: String
-    ): Set[NCDslIntent] = antlr4(U.readFile(filePath.toFile).mkString("\n"), mdlId, filePath.getFileName.toString)
-    
+    ): Set[NCDslIntent] = parseIntents(U.readFile(filePath.toFile).mkString("\n"), mdlId, filePath.getFileName.toString)
+
     /**
      * Compiles inline (supplied) fragments and/or intents. Note that fragments are accumulated in a static
      * map keyed by model ID. Only intents are returned, if any.
      *
-     * @param dsl DSL to compile.
+     * @param dsl Intent DSL to compile.
      * @param mdlId ID of the model DSL belongs to.
      * @param srcName Optional source name.
      * @return
      */
     @throws[NCE]
-    def compileIntent(
+    def compileIntents(
         dsl: String,
         mdlId: String,
         srcName: String = "<inline>"
-    ): Set[NCDslIntent] = antlr4(dsl, mdlId, srcName)
+    ): Set[NCDslIntent] = parseIntents(dsl, mdlId, srcName)
+
+    /**
+     *
+     * @param dsl Synonym DSL to compile.
+     * @param mdlId ID of the model DSL belongs to.
+     * @return
+     */
+    @throws[NCE]
+    def compileSynonym(
+        dsl: String,
+        mdlId: String
+    ): NCDslSynonym = parseSynonym(dsl, mdlId)
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/deploy/NCDeployManager.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/deploy/NCDeployManager.scala
index f470529..e63aceb 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/deploy/NCDeployManager.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/deploy/NCDeployManager.scala
@@ -1473,7 +1473,7 @@ object NCDeployManager extends NCService with DecorateAsScala {
             val mStr = method2Str(m)
 
             // Process inline intent declarations by @NCIntent annotation.
-            for (ann ← m.getAnnotationsByType(CLS_INTENT); intent ← NCIntentDslCompiler.compileIntent(ann.value(), mdl.getId, mStr))
+            for (ann ← m.getAnnotationsByType(CLS_INTENT); intent ← NCIntentDslCompiler.compileIntents(ann.value(), mdl.getId, mStr))
                 intents += (intent → prepareCallback(m, mdl, intent))
     
             // Process intent references from @NCIntentRef annotation.
@@ -1485,7 +1485,7 @@ object NCDeployManager extends NCService with DecorateAsScala {
                         val compiledIntents = adapter
                             .getIntents
                             .asScala
-                            .flatMap(NCIntentDslCompiler.compileIntent(_, mdl.getId, mStr))
+                            .flatMap(NCIntentDslCompiler.compileIntents(_, mdl.getId, mStr))
             
                         U.getDups(compiledIntents.toSeq.map(_.id)) match {
                             case ids if ids.nonEmpty ⇒
@@ -1554,7 +1554,7 @@ object NCDeployManager extends NCService with DecorateAsScala {
                     val distinct = seqSeq.map(_.distinct).distinct
 
                     for (ann ← intAnns) {
-                        for (intent ← NCIntentDslCompiler.compileIntent(ann.value(), mdlId, mStr))
+                        for (intent ← NCIntentDslCompiler.compileIntents(ann.value(), mdlId, mStr))
                             samples += (intent.id → distinct)
                     }
                     for (ann ← refAnns)
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/dsl/compiler/NCIntentDslCompilerSpec.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/dsl/compiler/NCIntentDslCompilerSpec.scala
index a7b2d95..685ea43 100644
--- a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/dsl/compiler/NCIntentDslCompilerSpec.scala
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/dsl/compiler/NCIntentDslCompilerSpec.scala
@@ -35,7 +35,7 @@ class NCIntentDslCompilerSpec {
      */
     private def checkCompileOk(dsl: String): Unit =
         try {
-            NCIntentDslCompiler.compileIntent(dsl, MODEL_ID)
+            NCIntentDslCompiler.compileIntents(dsl, MODEL_ID)
 
             assert(true)
         }
@@ -49,7 +49,7 @@ class NCIntentDslCompilerSpec {
       */
     private def checkPathCompileOk(path: Path): Unit =
         try {
-            NCIntentDslCompiler.compileIntent(path, MODEL_ID)
+            NCIntentDslCompiler.compileIntents(path, MODEL_ID)
             
             assert(true)
         }
@@ -63,7 +63,7 @@ class NCIntentDslCompilerSpec {
      */
     private def checkCompileError(txt: String): Unit =
         try {
-            NCIntentDslCompiler.compileIntent(txt, MODEL_ID)
+            NCIntentDslCompiler.compileIntents(txt, MODEL_ID)
 
             assert(false)
         } catch {