Code review + refactoring.
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/common/config/NCConfigurable.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/config/NCConfigurable.scala
index 934d9ae..aca2517 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/common/config/NCConfigurable.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/config/NCConfigurable.scala
@@ -329,7 +329,7 @@
             
             val lines = cfg.origin().description().split(",").drop(1).distinct
             
-            logger.info(s"Configuration successfully loaded as a merge of: ${lines.mkString("\n  + ", "\n  + ", "")}")
+            logger.info(s"NLPCraft configuration successfully loaded as a merge of: ${lines.mkString("\n  + ", "\n  + ", "")}")
         }
 
         // Set parsed configuration into Java shim.
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/common/nlp/NCNlpSentence.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/nlp/NCNlpSentence.scala
index db05f0d..62f91c8 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/common/nlp/NCNlpSentence.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/nlp/NCNlpSentence.scala
@@ -459,10 +459,12 @@
     @transient
     private var hash: java.lang.Integer = _
 
-    private def calcHash(): Int = Seq(srvReqId, text, enabledBuiltInToks, tokens).map(_.hashCode()).foldLeft(0)((a, b) ⇒ 31 * a + b)
+    private def calcHash(): Int =
+        Seq(srvReqId, text, enabledBuiltInToks, tokens).map(_.hashCode()).foldLeft(0)((a, b) ⇒ 31 * a + b)
 
     // Deep copy.
-    override def clone(): NCNlpSentence = new NCNlpSentence(srvReqId, text, weight, enabledBuiltInToks, tokens.map(_.clone()))
+    override def clone(): NCNlpSentence =
+        new NCNlpSentence(srvReqId, text, weight, enabledBuiltInToks, tokens.map(_.clone()))
 
     /**
       * Utility method that gets set of notes for given note type collected from
@@ -481,6 +483,7 @@
       */
     def removeNote(note: NCNlpSentenceNote): Unit = this.foreach(_.remove(note))
 
+    //noinspection HashCodeUsesVar
     override def hashCode(): Int = {
         if (hash == null)
             hash = calcHash()
@@ -597,7 +600,7 @@
                     val nlpNotes = notes.filter(_.isNlp)
                     val userNotes = notes.filter(_.isUser)
 
-                    def get(seq: Seq[NCNlpSentenceNote], keys2Skip: String*): Seq[Map[String, java.io.Serializable]] =
+                    def get(seq: Seq[NCNlpSentenceNote]): Seq[Map[String, java.io.Serializable]] =
                         seq.map(p ⇒
                             // We have to delete some keys to have possibility to compare sentences.
                             p.clone().filter(_._1 != "direct")
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/impl/NCTokenImpl.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/impl/NCTokenImpl.scala
index 39b4914..106f673 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/impl/NCTokenImpl.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/impl/NCTokenImpl.scala
@@ -23,7 +23,7 @@
 import org.apache.nlpcraft.common._
 import org.apache.nlpcraft.common.nlp.NCNlpSentenceToken
 import org.apache.nlpcraft.model._
-import org.apache.nlpcraft.probe.mgrs.nlp.NCModelData
+import org.apache.nlpcraft.probe.mgrs.NCProbeModel
 
 import scala.collection.JavaConverters._
 import scala.collection.{Seq, mutable}
@@ -99,7 +99,7 @@
 }
 
 private[nlpcraft] object NCTokenImpl {
-    def apply(mdl: NCModelData, srvReqId: String, tok: NCNlpSentenceToken): NCTokenImpl = {
+    def apply(mdl: NCProbeModel, srvReqId: String, tok: NCNlpSentenceToken): NCTokenImpl = {
         // nlpcraft:nlp and some optional (after collapsing).
         require(tok.size <= 2, s"Unexpected token [size=${tok.size}, token=$tok]")
 
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/impl/NCIntentSolverEngine.scala
index 5820fb7..cd2a6fe 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentSolverEngine.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentSolverEngine.scala
@@ -168,7 +168,7 @@
         startScopedSpan("solve",
             "srvReqId" → req.getServerRequestId,
             "userId" → req.getUser.getId,
-            "modelId" → ctx.getModel.getId,
+            "mdlId" → ctx.getModel.getId,
             "normText" → req.getNormalizedText) { _ ⇒
             val matches = mutable.ArrayBuffer.empty[MatchHolder]
 
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/impl/NCTestAutoModelValidatorImpl.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/impl/NCTestAutoModelValidatorImpl.scala
index ae87657..a9bebc0 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/impl/NCTestAutoModelValidatorImpl.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/tools/test/impl/NCTestAutoModelValidatorImpl.scala
@@ -61,7 +61,7 @@
         NCEmbeddedProbe.start(classes: _*)
 
         try
-            process(NCModelManager.getAllModelsData().map(p ⇒ p.model.getId → p.samples.toMap).toMap.filter(_._2.nonEmpty))
+            process(NCModelManager.getAllModels().map(p ⇒ p.model.getId → p.samples.toMap).toMap.filter(_._2.nonEmpty))
         finally
             NCEmbeddedProbe.stop()
     }
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
new file mode 100644
index 0000000..2bca270
--- /dev/null
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeModel.scala
@@ -0,0 +1,49 @@
+/*
+ * 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.probe.mgrs
+
+import org.apache.nlpcraft.model.intent.impl.NCIntentSolver
+import org.apache.nlpcraft.model.intent.utils.NCDslIntent
+import org.apache.nlpcraft.model.{NCElement, NCModel}
+
+import scala.collection.{Map, Seq}
+
+/**
+  *
+  * @param model
+  * @param solver
+  * @param intents
+  * @param synonyms
+  * @param synonymsDsl
+  * @param addStopWordsStems
+  * @param exclStopWordsStems
+  * @param suspWordsStems
+  * @param elements
+  */
+case class NCProbeModel(
+    model: NCModel,
+    solver: NCIntentSolver,
+    intents: Seq[NCDslIntent],
+    synonyms: Map[String /*Element ID*/ , Map[Int /*Synonym length*/ , Seq[NCProbeSynonym]]], // Fast access map.
+    synonymsDsl: Map[String /*Element ID*/ , Map[Int /*Synonym length*/ , Seq[NCProbeSynonym]]], // Fast access map.
+    addStopWordsStems: Set[String],
+    exclStopWordsStems: Set[String],
+    suspWordsStems: Set[String],
+    elements: Map[String /*Element ID*/ , NCElement],
+    samples: Map[String, Seq[String]]
+)
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCSynonym.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeSynonym.scala
similarity index 94%
rename from nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCSynonym.scala
rename to nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeSynonym.scala
index 0ccb701..8e3258e 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCSynonym.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeSynonym.scala
@@ -19,7 +19,7 @@
 
 import org.apache.nlpcraft.common.nlp.{NCNlpSentenceToken, NCNlpSentenceTokenBuffer}
 import org.apache.nlpcraft.model._
-import org.apache.nlpcraft.probe.mgrs.NCSynonymChunkKind._
+import org.apache.nlpcraft.probe.mgrs.NCProbeSynonymChunkKind._
 
 import scala.collection.mutable.ArrayBuffer
 
@@ -32,12 +32,12 @@
   * @param isDirect Direct or permutated synonym flag.
   * @param value Optional value name if this is a value synonym.
   */
-class NCSynonym(
+class NCProbeSynonym(
     val isElementId: Boolean,
     val isValueName: Boolean,
     val isDirect: Boolean,
     val value: String = null
-) extends ArrayBuffer[NCSynonymChunk] with Ordered[NCSynonym] {
+) extends ArrayBuffer[NCProbeSynonymChunk] with Ordered[NCProbeSynonym] {
     require((isElementId && !isValueName && value == null) || !isElementId)
     require((isValueName && value != null) || !isValueName)
     
@@ -125,7 +125,7 @@
     override def toString(): String = mkString(" ")
     
     // Orders synonyms from least to most significant.
-    override def compare(that: NCSynonym): Int = {
+    override def compare(that: NCProbeSynonym): Int = {
         def compareIsValueSynonym(): Int =
             isValueSynonym match {
                 case true if !that.isValueSynonym ⇒ 1
@@ -171,10 +171,10 @@
             }
     }
     
-    override def canEqual(other: Any): Boolean = other.isInstanceOf[NCSynonym]
+    override def canEqual(other: Any): Boolean = other.isInstanceOf[NCProbeSynonym]
     
     override def equals(other: Any): Boolean = other match {
-        case that: NCSynonym ⇒
+        case that: NCProbeSynonym ⇒
             super.equals(that) &&
                 (that canEqual this) &&
                 isTextOnly == that.isTextOnly &&
@@ -203,7 +203,7 @@
     }
 }
 
-object NCSynonym {
+object NCProbeSynonym {
     /**
       *
       * @param isElementId
@@ -213,8 +213,8 @@
       * @param chunks
       * @return
       */
-    def apply(isElementId: Boolean, isValueName: Boolean, isDirect: Boolean, value: String, chunks: Seq[NCSynonymChunk]): NCSynonym = {
-        var syn = new NCSynonym(isElementId, isValueName, isDirect, value)
+    def apply(isElementId: Boolean, isValueName: Boolean, isDirect: Boolean, value: String, chunks: Seq[NCProbeSynonymChunk]): NCProbeSynonym = {
+        var syn = new NCProbeSynonym(isElementId, isValueName, isDirect, value)
         
         syn ++= chunks
         
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCSynonymChunk.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeSynonymChunk.scala
similarity index 94%
rename from nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCSynonymChunk.scala
rename to nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeSynonymChunk.scala
index bebd69a..32aadca 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCSynonymChunk.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeSynonymChunk.scala
@@ -20,7 +20,7 @@
 import java.util.regex.Pattern
 
 import org.apache.nlpcraft.model.NCToken
-import org.apache.nlpcraft.probe.mgrs.NCSynonymChunkKind._
+import org.apache.nlpcraft.probe.mgrs.NCProbeSynonymChunkKind._
 
 /**
  *
@@ -32,7 +32,7 @@
  * @param regex Optional regex expression to match on.
  * @param dslPred Optional DSL expression to match on.
  */
-case class NCSynonymChunk(
+case class NCProbeSynonymChunk(
     alias: String = null, // Not-null only for kind == DSL.
     kind: NCSynonymChunkKind,
     origText: String,
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCSynonymChunkKind.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeSynonymChunkKind.scala
similarity index 95%
rename from nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCSynonymChunkKind.scala
rename to nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeSynonymChunkKind.scala
index 7f1e645..9394d0f 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCSynonymChunkKind.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeSynonymChunkKind.scala
@@ -20,7 +20,7 @@
 /**
   * Synonym element type.
   */
-object NCSynonymChunkKind extends Enumeration {
+object NCProbeSynonymChunkKind extends Enumeration {
     type NCSynonymChunkKind = Value
     
     val TEXT: Value = Value // Simple word.
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCModelData.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeVariants.scala
similarity index 65%
rename from nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCModelData.scala
rename to nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeVariants.scala
index 22706df..163bee1 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCModelData.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeVariants.scala
@@ -1,63 +1,56 @@
-package org.apache.nlpcraft.probe.mgrs.nlp
+/*
+ * 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.probe.mgrs
 
 import java.io.Serializable
 import java.util
 
 import org.apache.nlpcraft.common.TOK_META_ALIASES_KEY
 import org.apache.nlpcraft.common.nlp.NCNlpSentence
+import org.apache.nlpcraft.model.NCVariant
 import org.apache.nlpcraft.model.impl.{NCTokenImpl, NCVariantImpl}
-import org.apache.nlpcraft.model.intent.impl.NCIntentSolver
-import org.apache.nlpcraft.model.{NCElement, NCModel, NCVariant}
-import org.apache.nlpcraft.probe.mgrs.NCSynonym
 
 import scala.collection.JavaConverters._
-import scala.collection.{Map, Seq, mutable}
+import scala.collection.{Seq, mutable}
 
 /**
-  *
-  * @param model
-  * @param solver
-  * @param synonyms
-  * @param synonymsDsl
-  * @param addStopWordsStems
-  * @param exclStopWordsStems
-  * @param suspWordsStems
-  * @param elements
+  * Sentence to variants converter.
   */
-case class NCModelData(
-    model: NCModel,
-    solver: NCIntentSolver,
-    synonyms: Map[String /*Element ID*/ , Map[Int /*Synonym length*/ , Seq[NCSynonym]]], // Fast access map.
-    synonymsDsl: Map[String /*Element ID*/ , Map[Int /*Synonym length*/ , Seq[NCSynonym]]], // Fast access map.
-    addStopWordsStems: Set[String],
-    exclStopWordsStems: Set[String],
-    suspWordsStems: Set[String],
-    elements: Map[String /*Element ID*/ , NCElement],
-    samples: Map[String, Seq[String]]
-) {
+object NCProbeVariants {
     /**
-      * Makes variants for given sentences.
+      * Makes variants for given sentences for given model.
       *
+      * @param mdl Probe model.
       * @param srvReqId Server request ID.
       * @param sens Sentences.
       */
-    def makeVariants(srvReqId: String, sens: Seq[NCNlpSentence]): Seq[NCVariant] = {
-        val seq = sens.map(_.toSeq.map(nlpTok ⇒ NCTokenImpl(this, srvReqId, nlpTok) → nlpTok))
+    def convert(srvReqId: String, mdl: NCProbeModel, sens: Seq[NCNlpSentence]): Seq[NCVariant] = {
+        val seq = sens.map(_.toSeq.map(nlpTok ⇒ NCTokenImpl(mdl, srvReqId, nlpTok) → nlpTok))
         val toks = seq.map(_.map { case (tok, _) ⇒ tok })
-
         case class Key(id: String, from: Int, to: Int)
-
+    
         val keys2Toks = toks.flatten.map(t ⇒ Key(t.getId, t.getStartCharIndex, t.getEndCharIndex) → t).toMap
         val partsKeys = mutable.HashSet.empty[Key]
-
         seq.flatten.foreach { case (tok, tokNlp) ⇒
             if (tokNlp.isUser) {
                 val userNotes = tokNlp.filter(_.isUser)
-
                 require(userNotes.size == 1)
-
                 val optList: Option[util.List[util.HashMap[String, Serializable]]] = userNotes.head.dataOpt("parts")
-
                 optList match {
                     case Some(list) ⇒
                         val keys =
@@ -69,14 +62,12 @@
                                 )
                             )
                         val parts = keys.map(keys2Toks)
-
                         parts.zip(list.asScala).foreach { case (part, map) ⇒
                             map.get(TOK_META_ALIASES_KEY) match {
                                 case null ⇒ // No-op.
                                 case aliases ⇒ part.getMetadata.put(TOK_META_ALIASES_KEY, aliases.asInstanceOf[Object])
                             }
                         }
-
                         tok.setParts(parts)
                         partsKeys ++= keys
 
@@ -84,7 +75,7 @@
                 }
             }
         }
-
+    
         //  We can't collapse parts earlier, because we need them here (setParts method, few lines above.)
         toks.filter(sen ⇒
             !sen.exists(t ⇒
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/cmd/NCCommandManager.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/cmd/NCCommandManager.scala
index 05c4367..c8ffc5c 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/cmd/NCCommandManager.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/cmd/NCCommandManager.scala
@@ -71,7 +71,7 @@
             "msgType" → msg.getType,
             "srvReqId" → msg.dataOpt[String]("srvReqId").getOrElse(""),
             "usrId" → msg.dataOpt[Long]("userId").getOrElse(-1),
-            "modelId" → msg.dataOpt[String]("mdlId").getOrElse("")) { span ⇒
+            "mdlId" → msg.dataOpt[String]("mdlId").getOrElse("")) { span ⇒
             if (msg.getType != "S2P_PING")
                 logger.trace(s"Probe server message received: $msg")
             
@@ -108,7 +108,7 @@
                     case "S2P_MODEL_INFO" ⇒
                         val mdlId = msg.data[String]("mdlId")
 
-                        val mdlData = NCModelManager.getModelData(mdlId)
+                        val mdlData = NCModelManager.getModel(mdlId)
 
                         val macros = mdlData.model.getMacros.asInstanceOf[Serializable]
                         val syns = mdlData.model.getElements.asScala.map(p ⇒ p.getId → p.getSynonyms).toMap.asJava.asInstanceOf[Serializable]
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/conn/NCConnectionManager.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/conn/NCConnectionManager.scala
index 8fee8d6..529c2b5 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/conn/NCConnectionManager.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/conn/NCConnectionManager.scala
@@ -227,7 +227,7 @@
                     "PROBE_HOST_ADDR" → localHost.getHostAddress,
                     "PROBE_HW_ADDR" → hwAddrs,
                     "PROBE_MODELS" →
-                        NCModelManager.getAllModelsData().map(wrapper ⇒ {
+                        NCModelManager.getAllModels().map(wrapper ⇒ {
                             val mdl = wrapper.model
 
                             // Model already validated.
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/conversation/NCConversationManager.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/conversation/NCConversationManager.scala
index 3479d5f..1e8e9f2 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/conversation/NCConversationManager.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/conversation/NCConversationManager.scala
@@ -78,7 +78,7 @@
                 val delKeys = ArrayBuffer.empty[Key]
 
                 for ((key, value) ← convs)
-                    NCModelManager.getModelDataOpt(key.mdlId) match {
+                    NCModelManager.getModelOpt(key.mdlId) match {
                         case Some(data) ⇒
                             if (value.tstamp < System.currentTimeMillis() - data.model.getConversationTimeout)
                                 delKeys += key
@@ -99,7 +99,7 @@
       */
     def getConversation(usrId: Long, mdlId: String, parent: Span = null): NCConversation =
         startScopedSpan("getConversation", parent, "usrId" → usrId, "mdlId" → mdlId) { _ ⇒
-            val mdl = NCModelManager.getModelData(mdlId).model
+            val mdl = NCModelManager.getModel(mdlId).model
 
             convs.synchronized {
                 val v = convs.getOrElseUpdate(
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 29b90eb..3501691 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
@@ -35,10 +35,9 @@
 import org.apache.nlpcraft.model.factories.basic.NCBasicModelFactory
 import org.apache.nlpcraft.model.intent.impl.{NCIntentDslCompiler, NCIntentSolver}
 import org.apache.nlpcraft.model.intent.utils.NCDslIntent
-import org.apache.nlpcraft.probe.mgrs.NCSynonymChunkKind.{DSL, REGEX, TEXT}
-import org.apache.nlpcraft.probe.mgrs.{NCSynonym, NCSynonymChunk}
+import org.apache.nlpcraft.probe.mgrs.NCProbeSynonymChunkKind.{DSL, REGEX, TEXT}
+import org.apache.nlpcraft.probe.mgrs.{NCProbeModel, NCProbeSynonym, NCProbeSynonymChunk}
 import org.apache.nlpcraft.probe.mgrs.model.NCModelSynonymDslCompiler
-import org.apache.nlpcraft.probe.mgrs.nlp.NCModelData
 import resource.managed
 
 import scala.collection.JavaConverters._
@@ -81,7 +80,7 @@
 
     type Callback = Function[NCIntentMatch, NCResult]
 
-    @volatile private var data: ArrayBuffer[NCModelData] = _
+    @volatile private var data: ArrayBuffer[NCProbeModel] = _
     @volatile private var modelFactory: NCModelFactory = _
 
     object Config extends NCConfigurable {
@@ -99,7 +98,7 @@
       * @param elmId Element ID.
       * @param syn Element synonym.
       */
-    case class SynonymHolder(elmId: String, syn: NCSynonym)
+    case class SynonymHolder(elmId: String, syn: NCProbeSynonym)
 
     /**
       * Gives a list of JAR files at given path.
@@ -134,7 +133,7 @@
       * @return
       */
     @throws[NCE]
-    private def wrap(mdl: NCModel): NCModelData = {
+    private def wrap(mdl: NCModel): NCProbeModel = {
         require(mdl != null)
 
         checkModelConfig(mdl)
@@ -198,11 +197,11 @@
                 isElementId: Boolean,
                 isValueName: Boolean,
                 value: String,
-                chunks: Seq[NCSynonymChunk]): Unit = {
-                def add(chunks: Seq[NCSynonymChunk], isDirect: Boolean): Unit = {
+                chunks: Seq[NCProbeSynonymChunk]): Unit = {
+                def add(chunks: Seq[NCProbeSynonymChunk], isDirect: Boolean): Unit = {
                     val holder = SynonymHolder(
                         elmId = elmId,
-                        syn = NCSynonym(isElementId, isValueName, isDirect, value, chunks)
+                        syn = NCProbeSynonym(isElementId, isValueName, isDirect, value, chunks)
                     )
 
                     if (syns.add(holder)) {
@@ -247,7 +246,7 @@
               * @return
               */
             @throws[NCE]
-            def chunkSplit(s: String): Seq[NCSynonymChunk] = {
+            def chunkSplit(s: String): Seq[NCProbeSynonymChunk] = {
                 val x = s.trim()
 
                 val chunks = ListBuffer.empty[String]
@@ -297,7 +296,7 @@
               * @param id
               */
             @throws[NCE]
-            def chunkIdSplit(id: String): Seq[NCSynonymChunk] = {
+            def chunkIdSplit(id: String): Seq[NCProbeSynonymChunk] = {
                 val chunks = chunkSplit(NCNlpCoreManager.tokenize(id).map(_.token).mkString(" "))
 
                 // IDs can only be simple strings.
@@ -481,9 +480,10 @@
         else
             logger.warn(s"Model has no intents [mdlId=$mdlId]")
 
-        NCModelData(
+        NCProbeModel(
             model = mdl,
             solver = solver,
+            intents = intents.keySet.toSeq,
             synonyms = mkFastAccessMap(filter(syns, dsl = false)),
             synonymsDsl = mkFastAccessMap(filter(syns, dsl = true)),
             addStopWordsStems = addStopWords.toSet,
@@ -515,7 +515,7 @@
       * @param clsName Model class name.
       */
     @throws[NCE]
-    private def makeModelWrapper(clsName: String): NCModelData =
+    private def makeModelWrapper(clsName: String): NCProbeModel =
         try
             wrap(
                 makeModelFromSource(
@@ -532,7 +532,7 @@
       * @param set
       * @return
       */
-    private def mkFastAccessMap(set: Set[SynonymHolder]): Map[String /*Element ID*/ , Map[Int /*Synonym length*/ , Seq[NCSynonym]]] =
+    private def mkFastAccessMap(set: Set[SynonymHolder]): Map[String /*Element ID*/ , Map[Int /*Synonym length*/ , Seq[NCProbeSynonym]]] =
         set
             .groupBy(_.elmId)
             .map {
@@ -571,7 +571,7 @@
       * @param jarFile JAR file to extract from.
       */
     @throws[NCE]
-    private def extractModels(jarFile: File): Seq[NCModelData] = {
+    private def extractModels(jarFile: File): Seq[NCProbeModel] = {
         val clsLdr = Thread.currentThread().getContextClassLoader
 
         val classes = mutable.ArrayBuffer.empty[Class[_ <: NCModel]]
@@ -610,7 +610,7 @@
 
     @throws[NCE]
     override def start(parent: Span = null): NCService = startScopedSpan("start", parent) { _ ⇒
-        data = ArrayBuffer.empty[NCModelData]
+        data = ArrayBuffer.empty[NCProbeModel]
 
         modelFactory = new NCBasicModelFactory
 
@@ -667,7 +667,7 @@
       *
       * @return
       */
-    def getModels: Seq[NCModelData] = data
+    def getModels: Seq[NCProbeModel] = data
 
     /**
       * Permutes and drops duplicated.
@@ -916,7 +916,7 @@
      * @return
      */
     @throws[NCE]
-    private def mkChunk(mdlId: String, chunk: String): NCSynonymChunk = {
+    private def mkChunk(mdlId: String, chunk: String): NCProbeSynonymChunk = {
         def stripSuffix(fix: String, s: String): String = s.slice(fix.length, s.length - fix.length)
 
         // Regex synonym.
@@ -925,7 +925,7 @@
 
             if (ptrn.length > 0)
                 try
-                    NCSynonymChunk(kind = REGEX, origText = chunk, regex = Pattern.compile(ptrn))
+                    NCProbeSynonymChunk(kind = REGEX, origText = chunk, regex = Pattern.compile(ptrn))
                 catch {
                     case e: PatternSyntaxException ⇒
                         throw new NCE(s"Invalid regex synonym syntax detected [" +
@@ -944,13 +944,13 @@
             val dsl = stripSuffix(DSL_FIX, chunk)
             val compUnit = NCModelSynonymDslCompiler.parse(dsl)
 
-            val x = NCSynonymChunk(alias = compUnit.alias, kind = DSL, origText = chunk, dslPred = compUnit.predicate)
+            val x = NCProbeSynonymChunk(alias = compUnit.alias, kind = DSL, origText = chunk, dslPred = compUnit.predicate)
 
             x
         }
         // Regular word.
         else
-            NCSynonymChunk(kind = TEXT, origText = chunk, wordStem = NCNlpCoreManager.stem(chunk))
+            NCProbeSynonymChunk(kind = TEXT, origText = chunk, wordStem = NCNlpCoreManager.stem(chunk))
     }
 
     /**
@@ -1075,14 +1075,12 @@
                 }
             }
 
-
         if (U.containsDups(termIds))
-            throw new NCE(s"@NCIntentTerm values duplicated [" +
+            throw new NCE(s"Duplicate term IDs in @NCIntentTerm annotations [" +
                 s"mdlId=$mdlId, " +
-                s"duplicated=${U.getDups(termIds).mkString(", ")}, " +
+                s"dups=${U.getDups(termIds).mkString(", ")}, " +
                 s"callback=${method2Str(mtd)}" +
-                s"]"
-            )
+            s"]")
 
         val terms = intent.terms.toSeq
 
@@ -1490,9 +1488,8 @@
                                 logger.warn(s"@NCTestSample annotation has duplicates [" +
                                     s"mdlId=$mdlId, " +
                                     s"callback=$mkMethodName, " +
-                                    s"duplicated=${U.getDups(samples).mkString(", ")}" +
-                                    s"]"
-                                )
+                                    s"dups=${U.getDups(samples).mkString("'", ", ", "'")}" +
+                                s"]")
 
                                 Some(mkIntentId() → samples.distinct)
                             }
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 eced14b..4b54447 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
@@ -111,7 +111,7 @@
                 val delKeys = ArrayBuffer.empty[Key]
 
                 for ((key, values) ← flow)
-                    NCModelManager.getModelDataOpt(key.mdlId) match {
+                    NCModelManager.getModelOpt(key.mdlId) match {
                         case Some(data) ⇒
                             val ms = System.currentTimeMillis() - data.model.getDialogTimeout
 
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/NCModelManager.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/NCModelManager.scala
index be6e8d6..26b463f 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/NCModelManager.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/model/NCModelManager.scala
@@ -21,8 +21,8 @@
 import org.apache.nlpcraft.common._
 import org.apache.nlpcraft.common.ascii.NCAsciiTable
 import org.apache.nlpcraft.model._
+import org.apache.nlpcraft.probe.mgrs.NCProbeModel
 import org.apache.nlpcraft.probe.mgrs.deploy._
-import org.apache.nlpcraft.probe.mgrs.nlp.NCModelData
 
 import scala.collection.convert.DecorateAsScala
 import scala.util.control.Exception._
@@ -32,14 +32,14 @@
   */
 object NCModelManager extends NCService with DecorateAsScala {
     // Deployed models keyed by their IDs.
-    @volatile private var data: Map[String, NCModelData] = _
+    @volatile private var data: Map[String, NCProbeModel] = _
 
     // Access mutex.
     private final val mux = new Object()
 
     @throws[NCE]
     override def start(parent: Span = null): NCService = startScopedSpan("start", parent) { span ⇒
-        val tbl = NCAsciiTable("Model ID", "Name", "Ver.", "Elements", "Synonyms")
+        val tbl = NCAsciiTable("Model ID", "Name", "Ver.", "Elements", "Synonyms", "Intents")
 
         mux.synchronized {
             data = NCDeployManager.getModels.map(w ⇒ {
@@ -58,7 +58,8 @@
                     mdl.getName,
                     mdl.getVersion,
                     w.elements.keySet.size,
-                    synCnt
+                    synCnt,
+                    w.intents.size
                 )
             })
         }
@@ -104,7 +105,7 @@
       *
       * @return
       */
-    def getAllModelsData(parent: Span = null): List[NCModelData] =
+    def getAllModels(parent: Span = null): List[NCProbeModel] =
         startScopedSpan("getAllModels", parent) { _ ⇒
             mux.synchronized { data.values.toList }
         }
@@ -113,8 +114,8 @@
       *
       * @param mdlId Model ID.
       */
-    def getModelDataOpt(mdlId: String, parent: Span = null): Option[NCModelData] =
-        startScopedSpan("getModelOpt", parent, "modelId" → mdlId) { _ ⇒
+    def getModelOpt(mdlId: String, parent: Span = null): Option[NCProbeModel] =
+        startScopedSpan("getModelOpt", parent, "mdlId" → mdlId) { _ ⇒
             mux.synchronized { data.get(mdlId) }
         }
 
@@ -122,6 +123,6 @@
      *
      * @param mdlId Model ID.
      */
-    def getModelData(mdlId: String, parent: Span = null): NCModelData =
-        getModelDataOpt(mdlId, parent).getOrElse(throw new NCE(s"Model not found: $mdlId"))
+    def getModel(mdlId: String, parent: Span = null): NCProbeModel =
+        getModelOpt(mdlId, parent).getOrElse(throw new NCE(s"Model not found: $mdlId"))
 }
\ No newline at end of file
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCProbeEnricher.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCProbeEnricher.scala
index 09e06cc..e6430ff 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCProbeEnricher.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCProbeEnricher.scala
@@ -23,6 +23,7 @@
 import io.opencensus.trace.Span
 import org.apache.nlpcraft.common.nlp._
 import org.apache.nlpcraft.common.{NCService, _}
+import org.apache.nlpcraft.probe.mgrs.NCProbeModel
 
 import scala.collection.Map
 import scala.language.implicitConversions
@@ -41,5 +42,5 @@
       * @param parent Span parent.
       */
     @throws[NCE]
-    def enrich(mdlData: NCModelData, ns: NCNlpSentence, senMeta: Map[String, Serializable], parent: Span): Unit
+    def enrich(mdlData: NCProbeModel, ns: NCNlpSentence, senMeta: Map[String, Serializable], parent: Span): Unit
 }
\ No newline at end of file
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 5db75e8..76efd7a 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
@@ -34,7 +34,7 @@
 import org.apache.nlpcraft.model.intent.impl.NCIntentSolverInput
 import org.apache.nlpcraft.model.opencensus.stats.NCOpenCensusModelStats
 import org.apache.nlpcraft.model.tools.embedded.NCEmbeddedResult
-import org.apache.nlpcraft.probe.mgrs.NCProbeMessage
+import org.apache.nlpcraft.probe.mgrs.{NCProbeMessage, NCProbeVariants}
 import org.apache.nlpcraft.probe.mgrs.conn.NCConnectionManager
 import org.apache.nlpcraft.probe.mgrs.conversation.NCConversationManager
 import org.apache.nlpcraft.probe.mgrs.dialogflow.NCDialogFlowManager
@@ -154,7 +154,7 @@
             "srvReqId" → srvReqId,
             "txt" → txt,
             "usrId" → usrId,
-            "modelId" → mdlId
+            "mdlId" → mdlId
         )
     
         try
@@ -318,14 +318,14 @@
                 logger.info(s"REJECT response $msgName sent [srvReqId=$srvReqId, response=${errMsg.get}]")
         }
 
-        val mdlData = NCModelManager.getModelData(mdlId, span)
+        val mdl = NCModelManager.getModel(mdlId, span)
 
         var errData: Option[(String, Int)] = None
 
         val validNlpSens =
             nlpSens.flatMap(nlpSen ⇒
                 try {
-                    NCValidateManager.preValidate(mdlData, nlpSen, span)
+                    NCValidateManager.preValidate(mdl, nlpSen, span)
 
                     Some(nlpSen)
                 }
@@ -362,14 +362,14 @@
 
         val sensSeq = validNlpSens.flatMap(nlpSen ⇒ {
             // Independent of references.
-            NCDictionaryEnricher.enrich(mdlData, nlpSen, senMeta, span)
-            NCSuspiciousNounsEnricher.enrich(mdlData, nlpSen, senMeta, span)
-            NCStopWordEnricher.enrich(mdlData, nlpSen, senMeta, span)
+            NCDictionaryEnricher.enrich(mdl, nlpSen, senMeta, span)
+            NCSuspiciousNounsEnricher.enrich(mdl, nlpSen, senMeta, span)
+            NCStopWordEnricher.enrich(mdl, nlpSen, senMeta, span)
 
             case class Holder(enricher: NCProbeEnricher, getNotes: () ⇒ Seq[NCNlpSentenceNote])
 
             def get(name: String, e: NCProbeEnricher): Option[Holder] =
-                if (mdlData.model.getEnabledBuiltInTokens.contains(name))
+                if (mdl.model.getEnabledBuiltInTokens.contains(name))
                     Some(Holder(e, () ⇒ nlpSen.flatten.filter(_.noteType == name)))
                 else
                     None
@@ -395,7 +395,7 @@
                     def get(): Seq[NCNlpSentenceNote] = h.getNotes().sortBy(p ⇒ (p.tokenIndexes.head, p.noteType))
                     val notes1 = get()
 
-                    h.enricher.enrich(mdlData, nlpSen, senMeta, span)
+                    h.enricher.enrich(mdl, nlpSen, senMeta, span)
 
                     val notes2 = get()
 
@@ -439,7 +439,7 @@
                 }).toMap
 
                 // Loop has sense if model is complex (has user defined parsers or DSL based synonyms)
-                continue = NCModelEnricher.isComplex(mdlData) && res.exists { case (_, same) ⇒ !same }
+                continue = NCModelEnricher.isComplex(mdl) && res.exists { case (_, same) ⇒ !same }
 
                 if (DEEP_DEBUG)
                     if (continue) {
@@ -474,7 +474,7 @@
 
         // Final validation before execution.
         try
-            sensSeq.foreach(NCValidateManager.postValidate(mdlData, _, span))
+            sensSeq.foreach(NCValidateManager.postValidate(mdl, _, span))
         catch {
             case e: NCValidateException ⇒
                 val (errMsg, errCode) = getError(e.code)
@@ -497,13 +497,13 @@
         val meta = mutable.HashMap.empty[String, Any] ++ senMeta
         val req = NCRequestImpl(meta, srvReqId)
 
-        var senVars = mdlData.makeVariants(srvReqId, sensSeq)
+        var senVars = NCProbeVariants.convert(srvReqId, mdl, sensSeq)
 
         // Sentence variants can be filtered by model.
         val fltSenVars: Seq[(NCVariant, Int)] =
             senVars.
             zipWithIndex.
-            flatMap { case (variant, i) ⇒ if (mdlData.model.onParsedVariant(variant)) Some(variant, i) else None }
+            flatMap { case (variant, i) ⇒ if (mdl.model.onParsedVariant(variant)) Some(variant, i) else None }
 
         senVars = fltSenVars.map(_._1)
         val allVars = senVars.flatMap(_.asScala)
@@ -538,7 +538,7 @@
         // Create model query context.
         val ctx: NCContext = new NCContext {
             override lazy val getRequest: NCRequest = req
-            override lazy val getModel: NCModel = mdlData.model
+            override lazy val getModel: NCModel = mdl.model
             override lazy val getServerRequestId: String = srvReqId
 
             override lazy val getConversation: NCConversation = new NCConversation {
@@ -556,7 +556,7 @@
         
             logKey = U.mkLogHolderKey(srvReqId)
         
-            val meta = mdlData.model.getMetadata
+            val meta = mdl.model.getMetadata
         
             meta.synchronized {
                 meta.put(logKey, logHldr)
@@ -582,7 +582,7 @@
         
         def onFinish(): Unit = {
             if (logKey != null)
-                mdlData.model.getMetadata.remove(logKey)
+                mdl.model.getMetadata.remove(logKey)
             
             span.end()
         }
@@ -592,16 +592,16 @@
         // Execute model query asynchronously.
         U.asFuture(
             _ ⇒ {
-                var res = mdlData.model.onContext(ctx)
+                var res = mdl.model.onContext(ctx)
     
                 start = System.currentTimeMillis()
     
-                if (res == null && mdlData.solver != null)
+                if (res == null && mdl.solver != null)
                     startScopedSpan("intentMatching", span) { _ ⇒
-                        res = mdlData.solver.solve(solverIn, span)
+                        res = mdl.solver.solve(solverIn, span)
                     }
                 
-                if (res == null && mdlData.solver == null)
+                if (res == null && mdl.solver == null)
                     throw new IllegalStateException("No intents and no results from model callbacks.")
     
                 recordStats(M_USER_LATENCY_MS → (System.currentTimeMillis() - start))
@@ -635,7 +635,7 @@
                         if (e.getCause != null)
                             logger.info(s"Rejection cause:", e.getCause)
     
-                        val res = mdlData.model.onRejection(solverIn.intentMatch, e)
+                        val res = mdl.model.onRejection(solverIn.intentMatch, e)
     
                         if (res != null)
                             respondWithResult(res, None)
@@ -664,7 +664,7 @@
                     
                         logger.error(s"Unexpected error for server request ID: $srvReqId", e)
         
-                        val res = mdlData.model.onError(ctx, e)
+                        val res = mdl.model.onError(ctx, e)
         
                         if (res != null)
                             respondWithResult(res, None)
@@ -690,7 +690,7 @@
                         "resBody" → res.getBody
                     )
                     
-                    val res0 = mdlData.model.onResult(solverIn.intentMatch, res)
+                    val res0 = mdl.model.onResult(solverIn.intentMatch, res)
 
                     respondWithResult(if (res0 != null) res0 else res, if (logHldr != null) Some(logHldr.toJson) else None)
                 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/dictionary/NCDictionaryEnricher.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/dictionary/NCDictionaryEnricher.scala
index 8619b91..b96e956 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/dictionary/NCDictionaryEnricher.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/dictionary/NCDictionaryEnricher.scala
@@ -24,7 +24,8 @@
 import org.apache.nlpcraft.common.nlp.core.NCNlpCoreManager
 import org.apache.nlpcraft.common.nlp.dict._
 import org.apache.nlpcraft.common.{NCService, _}
-import org.apache.nlpcraft.probe.mgrs.nlp.{NCModelData, NCProbeEnricher}
+import org.apache.nlpcraft.probe.mgrs.NCProbeModel
+import org.apache.nlpcraft.probe.mgrs.nlp.NCProbeEnricher
 
 import scala.collection.Map
 
@@ -53,10 +54,10 @@
     }
     
     @throws[NCE]
-    override def enrich(mdlData: NCModelData, ns: NCNlpSentence, senMeta: Map[String, Serializable], parent: Span = null): Unit =
+    override def enrich(mdl: NCProbeModel, ns: NCNlpSentence, senMeta: Map[String, Serializable], parent: Span = null): Unit =
         startScopedSpan("enrich", parent,
             "srvReqId" → ns.srvReqId,
-            "modelId" → mdlData.model.getId,
+            "mdlId" → mdl.model.getId,
             "txt" → ns.text) { _ ⇒
             ns.foreach(t ⇒ {
                 // Dictionary.
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/limit/NCLimitEnricher.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/limit/NCLimitEnricher.scala
index e9c1ff0..d7560b9 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/limit/NCLimitEnricher.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/limit/NCLimitEnricher.scala
@@ -25,7 +25,8 @@
 import org.apache.nlpcraft.common.nlp.numeric.{NCNumeric, NCNumericManager}
 import org.apache.nlpcraft.common.nlp.{NCNlpSentence, NCNlpSentenceNote, NCNlpSentenceToken}
 import org.apache.nlpcraft.common.{NCE, NCService}
-import org.apache.nlpcraft.probe.mgrs.nlp.{NCModelData, NCProbeEnricher}
+import org.apache.nlpcraft.probe.mgrs.NCProbeModel
+import org.apache.nlpcraft.probe.mgrs.nlp.NCProbeEnricher
 
 import scala.collection.JavaConverters._
 import scala.collection.{Map, Seq, mutable}
@@ -235,10 +236,10 @@
     }
 
     @throws[NCE]
-    override def enrich(mdlData: NCModelData, ns: NCNlpSentence, senMeta: Map[String, Serializable], parent: Span = null): Unit =
+    override def enrich(mdl: NCProbeModel, ns: NCNlpSentence, senMeta: Map[String, Serializable], parent: Span = null): Unit =
         startScopedSpan("enrich", parent,
             "srvReqId" → ns.srvReqId,
-            "modelId" → mdlData.model.getId,
+            "mdlId" → mdl.model.getId,
             "txt" → ns.text) { _ ⇒
             val notes = mutable.HashSet.empty[NCNlpSentenceNote]
             val numsMap = NCNumericManager.find(ns).filter(_.unit.isEmpty).map(p ⇒ p.tokens → p).toMap
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/model/NCModelEnricher.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/model/NCModelEnricher.scala
index f9174b0..420e6c4 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/model/NCModelEnricher.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/model/NCModelEnricher.scala
@@ -24,9 +24,9 @@
 import org.apache.nlpcraft.common._
 import org.apache.nlpcraft.common.nlp.{NCNlpSentenceToken, _}
 import org.apache.nlpcraft.model._
-import org.apache.nlpcraft.probe.mgrs.nlp.{NCModelData, NCProbeEnricher}
+import org.apache.nlpcraft.probe.mgrs.nlp.NCProbeEnricher
 import org.apache.nlpcraft.probe.mgrs.nlp.impl.NCRequestImpl
-import org.apache.nlpcraft.probe.mgrs.NCSynonym
+import org.apache.nlpcraft.probe.mgrs.{NCProbeModel, NCProbeSynonym, NCProbeVariants}
 
 import scala.collection.JavaConverters._
 import scala.collection.convert.DecorateAsScala
@@ -62,7 +62,7 @@
     case class ElementMatch(
         element: NCElement,
         tokens: Seq[NCNlpSentenceToken],
-        synonym: NCSynonym,
+        synonym: NCProbeSynonym,
         parts: Seq[NCToken]
     ) extends Ordered[ElementMatch] {
         // Tokens sparsity.
@@ -182,7 +182,7 @@
         elem: NCElement,
         toks: Seq[NCNlpSentenceToken],
         direct: Boolean,
-        syn: Option[NCSynonym],
+        syn: Option[NCProbeSynonym],
         metaOpt: Option[Map[String, Object]],
         parts: Seq[NCToken]
     ): Unit = {
@@ -297,15 +297,15 @@
       */
     private def alreadyMarked(toks: Seq[NCNlpSentenceToken], elemId: String): Boolean = toks.forall(_.isTypeOf(elemId))
 
-    def isComplex(mdl: NCModelData): Boolean = mdl.synonymsDsl.nonEmpty || !mdl.model.getParsers.isEmpty
+    def isComplex(mdl: NCProbeModel): Boolean = mdl.synonymsDsl.nonEmpty || !mdl.model.getParsers.isEmpty
 
     @throws[NCE]
-    override def enrich(mdlData: NCModelData, ns: NCNlpSentence, senMeta: Map[String, Serializable], parent: Span = null): Unit =
+    override def enrich(mdl: NCProbeModel, ns: NCNlpSentence, senMeta: Map[String, Serializable], parent: Span = null): Unit =
         startScopedSpan("enrich", parent,
             "srvReqId" → ns.srvReqId,
-            "modelId" → mdlData.model.getId,
+            "mdlId" → mdl.model.getId,
             "txt" → ns.text) { span ⇒
-            val jiggleFactor = mdlData.model.getJiggleFactor
+            val jiggleFactor = mdl.model.getJiggleFactor
             val cache = mutable.HashSet.empty[Seq[Int]]
             val matches = ArrayBuffer.empty[ElementMatch]
 
@@ -319,12 +319,12 @@
               * @return
               */
             def fastAccess(
-                fastMap: Map[String /*Element ID*/ , Map[Int /*Synonym length*/ , Seq[NCSynonym]]],
+                fastMap: Map[String /*Element ID*/ , Map[Int /*Synonym length*/ , Seq[NCProbeSynonym]]],
                 elmId: String,
-                len: Int): Seq[NCSynonym] =
+                len: Int): Seq[NCProbeSynonym] =
                 fastMap.get(elmId).flatMap(_.get(len)) match {
                     case Some(seq) ⇒ seq
-                    case None ⇒ Seq.empty[NCSynonym]
+                    case None ⇒ Seq.empty[NCProbeSynonym]
                 }
 
             /**
@@ -352,11 +352,11 @@
                         var seq: Seq[Seq[Complex]] = null
 
                         // Attempt to match each element.
-                        for (elm ← mdlData.elements.values if !alreadyMarked(toks, elm.getId)) {
+                        for (elm ← mdl.elements.values if !alreadyMarked(toks, elm.getId)) {
                             var found = false
 
                             def addMatch(
-                                elm: NCElement, toks: Seq[NCNlpSentenceToken], syn: NCSynonym, parts: Seq[NCToken]
+                                elm: NCElement, toks: Seq[NCNlpSentenceToken], syn: NCProbeSynonym, parts: Seq[NCToken]
                             ): Unit =
                                 if (!matches.exists(m ⇒ m.element == elm && m.isSubSet(toks.toSet))) {
                                     found = true
@@ -365,21 +365,21 @@
                                 }
 
                             // Optimization - plain synonyms can be used only on first iteration
-                            if (mdlData.synonyms.nonEmpty && !ns.exists(_.isUser))
-                                for (syn ← fastAccess(mdlData.synonyms, elm.getId, toks.length) if !found)
+                            if (mdl.synonyms.nonEmpty && !ns.exists(_.isUser))
+                                for (syn ← fastAccess(mdl.synonyms, elm.getId, toks.length) if !found)
                                     if (syn.isMatch(toks))
                                         addMatch(elm, toks, syn, Seq.empty)
 
-                            if (mdlData.synonymsDsl.nonEmpty) {
+                            if (mdl.synonymsDsl.nonEmpty) {
                                 found = false
 
                                 if (collapsedSens == null)
-                                    collapsedSens = mdlData.makeVariants(ns.srvReqId, ns.clone().collapse()).map(_.asScala)
+                                    collapsedSens = NCProbeVariants.convert(ns.srvReqId, mdl, ns.clone().collapse()).map(_.asScala)
 
                                 if (seq == null)
                                     seq = convert(ns, collapsedSens, toks)
 
-                                for (comb ← seq; syn ← fastAccess(mdlData.synonymsDsl, elm.getId, comb.length) if !found)
+                                for (comb ← seq; syn ← fastAccess(mdl.synonymsDsl, elm.getId, comb.length) if !found)
                                     if (syn.isMatch(comb.map(_.data)))
                                         addMatch(elm, toks, syn, comb.filter(_.isToken).map(_.token))
                             }
@@ -392,7 +392,7 @@
 
             startScopedSpan("jiggleProc", span,
                 "srvReqId" → ns.srvReqId,
-                "modelId" → mdlData.model.getId,
+                "mdlId" → mdl.model.getId,
                 "txt" → ns.text) { _ ⇒
                 // Iterate over depth-limited permutations of the original sentence with and without stopwords.
                 jiggle(ns, jiggleFactor).foreach(procPerm)
@@ -413,7 +413,7 @@
             for ((m, idx) ← matches.zipWithIndex) {
                 if (DEEP_DEBUG)
                     logger.trace(
-                        s"Model '${mdlData.model.getId}' element found (${idx + 1} of $matchCnt) [" +
+                        s"Model '${mdl.model.getId}' element found (${idx + 1} of $matchCnt) [" +
                             s"elementId=${m.element.getId}, " +
                             s"synonym=${m.synonym}, " +
                             s"tokens=${tokString(m.tokens)}" +
@@ -429,14 +429,14 @@
                 mark(ns, elem = elm, toks = m.tokens, direct = direct, syn = Some(syn), metaOpt = None, parts = m.parts)
             }
 
-            val parsers = mdlData.model.getParsers
+            val parsers = mdl.model.getParsers
 
             for (parser ← parsers.asScala) {
                 parser.onInit()
 
                 startScopedSpan("customParser", span,
                     "srvReqId" → ns.srvReqId,
-                    "modelId" → mdlData.model.getId,
+                    "mdlId" → mdl.model.getId,
                     "txt" → ns.text) { _ ⇒
                     def to(t: NCNlpSentenceToken): NCCustomWord =
                         new NCCustomWord {
@@ -458,7 +458,7 @@
 
                     val res = parser.parse(
                         NCRequestImpl(senMeta, ns.srvReqId),
-                        mdlData.model,
+                        mdl.model,
                         ns.map(to).asJava,
                         ns.flatten.distinct.filter(!_.isNlp).map(n ⇒ {
                             val noteId = n.noteType
@@ -494,7 +494,7 @@
                             if (!alreadyMarked(matchedToks, elemId))
                                 mark(
                                     ns,
-                                    elem = mdlData.elements.getOrElse(elemId, throw new NCE(s"Custom model parser returned unknown element ID: $elemId")),
+                                    elem = mdl.elements.getOrElse(elemId, throw new NCE(s"Custom model parser returned unknown element ID: $elemId")),
                                     toks = matchedToks,
                                     direct = true,
                                     syn = None,
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/relation/NCRelationEnricher.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/relation/NCRelationEnricher.scala
index b5ade6c..6f379b6 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/relation/NCRelationEnricher.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/relation/NCRelationEnricher.scala
@@ -24,7 +24,8 @@
 import org.apache.nlpcraft.common.nlp.core.NCNlpCoreManager
 import org.apache.nlpcraft.common.nlp.{NCNlpSentence, NCNlpSentenceNote, NCNlpSentenceToken}
 import org.apache.nlpcraft.common.{NCE, NCService}
-import org.apache.nlpcraft.probe.mgrs.nlp.{NCModelData, NCProbeEnricher}
+import org.apache.nlpcraft.probe.mgrs.NCProbeModel
+import org.apache.nlpcraft.probe.mgrs.nlp.NCProbeEnricher
 
 import scala.collection.JavaConverters._
 import scala.collection.{Map, Seq, mutable}
@@ -137,10 +138,10 @@
     }
 
     @throws[NCE]
-    override def enrich(mdlData: NCModelData, ns: NCNlpSentence, senMeta: Map[String, Serializable], parent: Span = null): Unit =
+    override def enrich(mdl: NCProbeModel, ns: NCNlpSentence, senMeta: Map[String, Serializable], parent: Span = null): Unit =
         startScopedSpan("enrich", parent,
             "srvReqId" → ns.srvReqId,
-            "modelId" → mdlData.model.getId,
+            "mdlId" → mdl.model.getId,
             "txt" → ns.text) { _ ⇒
             // Tries to grab tokens direct way.
             // Example: A, B, C ⇒ ABC, AB, BC .. (AB will be processed first)
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/sort/NCSortEnricher.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/sort/NCSortEnricher.scala
index c0e65e5..e331997 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/sort/NCSortEnricher.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/sort/NCSortEnricher.scala
@@ -24,7 +24,8 @@
 import org.apache.nlpcraft.common.makro.NCMacroParser
 import org.apache.nlpcraft.common.nlp.core.NCNlpCoreManager
 import org.apache.nlpcraft.common.nlp.{NCNlpSentence, NCNlpSentenceNote, NCNlpSentenceToken}
-import org.apache.nlpcraft.probe.mgrs.nlp.{NCModelData, NCProbeEnricher}
+import org.apache.nlpcraft.probe.mgrs.NCProbeModel
+import org.apache.nlpcraft.probe.mgrs.nlp.NCProbeEnricher
 
 import scala.collection.JavaConverters._
 import scala.collection.mutable.ArrayBuffer
@@ -414,10 +415,10 @@
         toks.length == toks2.length || toks.count(isImportant) == toks2.count(isImportant)
     }
 
-    override def enrich(mdlData: NCModelData, ns: NCNlpSentence, meta: Map[String, Serializable], parent: Span): Unit =
+    override def enrich(mdl: NCProbeModel, ns: NCNlpSentence, meta: Map[String, Serializable], parent: Span): Unit =
         startScopedSpan("enrich", parent,
             "srvReqId" → ns.srvReqId,
-            "modelId" → mdlData.model.getId,
+            "mdlId" → mdl.model.getId,
             "txt" → ns.text) { _ ⇒
             val notes = mutable.HashSet.empty[NCNlpSentenceNote]
 
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/stopword/NCStopWordEnricher.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/stopword/NCStopWordEnricher.scala
index cd2a434..8015d6c 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/stopword/NCStopWordEnricher.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/stopword/NCStopWordEnricher.scala
@@ -23,7 +23,8 @@
 import org.apache.nlpcraft.common.nlp.core.NCNlpCoreManager
 import org.apache.nlpcraft.common.nlp.{NCNlpSentence, NCNlpSentenceToken}
 import org.apache.nlpcraft.common.{NCE, NCService, U}
-import org.apache.nlpcraft.probe.mgrs.nlp.{NCModelData, NCProbeEnricher}
+import org.apache.nlpcraft.probe.mgrs.NCProbeModel
+import org.apache.nlpcraft.probe.mgrs.nlp.NCProbeEnricher
 
 import scala.annotation.tailrec
 import scala.collection.{Map, Seq}
@@ -175,12 +176,12 @@
     /**
       * Marks as stopwords, words with POS from configured list, which also placed before another stop words.
       */
-    private def processCommonStops(mdl: NCModelData, ns: NCNlpSentence): Unit = {
+    private def processCommonStops(mdl: NCProbeModel, ns: NCNlpSentence): Unit = {
         /**
           * Marks as stopwords, words with POS from configured list, which also placed before another stop words.
           */
         @tailrec
-        def processCommonStops0(mdl: NCModelData, ns: NCNlpSentence): Unit = {
+        def processCommonStops0(mdl: NCProbeModel, ns: NCNlpSentence): Unit = {
             val max = ns.size - 1
             var stop = true
 
@@ -205,19 +206,19 @@
     }
 
     @throws[NCE]
-    override def enrich(mdlData: NCModelData, ns: NCNlpSentence, senMeta: Map[String, Serializable], parent: Span = null): Unit = {
+    override def enrich(mdl: NCProbeModel, ns: NCNlpSentence, senMeta: Map[String, Serializable], parent: Span = null): Unit = {
         def mark(stems: Set[String], f: Boolean): Unit =
             ns.filter(t ⇒ stems.contains(t.stem)).foreach(t ⇒ ns.fixNote(t.getNlpNote, "stopWord" → f))
 
         startScopedSpan(
-            "enrich", parent, "srvReqId" → ns.srvReqId, "modelId" → mdlData.model.getId, "txt" → ns.text
+            "enrich", parent, "srvReqId" → ns.srvReqId, "mdlId" → mdl.model.getId, "txt" → ns.text
         ) { _ ⇒
-            mark(mdlData.exclStopWordsStems, f = false)
-            mark(mdlData.addStopWordsStems, f = true)
+            mark(mdl.exclStopWordsStems, f = false)
+            mark(mdl.addStopWordsStems, f = true)
             processGeo(ns)
             processDate(ns)
             processNums(ns)
-            processCommonStops(mdlData, ns)
+            processCommonStops(mdl, ns)
         }
     }
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/suspicious/NCSuspiciousNounsEnricher.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/suspicious/NCSuspiciousNounsEnricher.scala
index cf6c742..be8f984 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/suspicious/NCSuspiciousNounsEnricher.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/suspicious/NCSuspiciousNounsEnricher.scala
@@ -22,7 +22,8 @@
 import io.opencensus.trace.Span
 import org.apache.nlpcraft.common.{NCE, NCService}
 import org.apache.nlpcraft.common.nlp._
-import org.apache.nlpcraft.probe.mgrs.nlp.{NCModelData, NCProbeEnricher}
+import org.apache.nlpcraft.probe.mgrs.NCProbeModel
+import org.apache.nlpcraft.probe.mgrs.nlp.NCProbeEnricher
 
 import scala.collection.Map
 
@@ -39,11 +40,11 @@
     }
 
     @throws[NCE]
-    override def enrich(mdlData: NCModelData, ns: NCNlpSentence, senMeta: Map[String, Serializable], parent: Span = null): Unit =
+    override def enrich(mdl: NCProbeModel, ns: NCNlpSentence, senMeta: Map[String, Serializable], parent: Span = null): Unit =
         startScopedSpan("enrich", parent,
             "srvReqId" → ns.srvReqId,
-            "modelId" → mdlData.model.getId,
+            "mdlId" → mdl.model.getId,
             "txt" → ns.text) { _ ⇒
-            ns.filter(t ⇒ mdlData.suspWordsStems.contains(t.stem)).foreach(t ⇒ ns.fixNote(t.getNlpNote, "suspNoun" → true))
+            ns.filter(t ⇒ mdl.suspWordsStems.contains(t.stem)).foreach(t ⇒ ns.fixNote(t.getNlpNote, "suspNoun" → true))
         }
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/validate/NCValidateManager.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/validate/NCValidateManager.scala
index fe1b074..862c7df 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/validate/NCValidateManager.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/validate/NCValidateManager.scala
@@ -22,7 +22,7 @@
 import org.apache.tika.langdetect.OptimaizeLangDetector
 import org.apache.nlpcraft.common.NCService
 import org.apache.nlpcraft.common.nlp.NCNlpSentence
-import org.apache.nlpcraft.probe.mgrs.nlp.NCModelData
+import org.apache.nlpcraft.probe.mgrs.NCProbeModel
 
 /**
  * Probe pre/post enrichment validator.
@@ -51,11 +51,11 @@
      * @param parent Parent tracing span.
      */
     @throws[NCValidateException]
-    def preValidate(w: NCModelData, ns: NCNlpSentence, parent: Span = null): Unit =
+    def preValidate(w: NCProbeModel, ns: NCNlpSentence, parent: Span = null): Unit =
         startScopedSpan("validate", parent,
             "srvReqId" → ns.srvReqId,
             "txt" → ns.text,
-            "modelId" → w.model.getId) { _ ⇒
+            "mdlId" → w.model.getId) { _ ⇒
             val mdl = w.model
 
             if (!mdl.isNotLatinCharsetAllowed && !ns.text.matches("""[\s\w\p{Punct}]+"""))
@@ -77,11 +77,11 @@
      * @param parent Optional parent span.
      */
     @throws[NCValidateException]
-    def postValidate(w: NCModelData, ns: NCNlpSentence, parent: Span = null): Unit =
+    def postValidate(w: NCProbeModel, ns: NCNlpSentence, parent: Span = null): Unit =
         startScopedSpan("validate", parent,
             "srvReqId" → ns.srvReqId,
             "txt" → ns.text,
-            "modelId" → w.model.getId) { _ ⇒
+            "mdlId" → w.model.getId) { _ ⇒
             val mdl = w.model
             val types = ns.flatten.filter(!_.isNlp).map(_.noteType).distinct
             val overlapNotes = ns.map(tkn ⇒ types.flatMap(tp ⇒ tkn.getNotes(tp))).filter(_.size > 1).flatten
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/probe/NCProbeManager.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/probe/NCProbeManager.scala
index abdd5b6..20bf78b 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/probe/NCProbeManager.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/probe/NCProbeManager.scala
@@ -520,7 +520,7 @@
                     "OS",
                     "Timezone",
                     "Host",
-                    "Models"
+                    "Models Deployed"
                 )
             
                 addProbeToTable(tbl, holder).info(logger, Some("New probe registered:"))
@@ -810,7 +810,7 @@
             s"${probe.osName} ver. ${probe.osVersion}",
             s"${probe.tmzAbbr}, ${probe.tmzId}",
             s"${probe.hostName} (${probe.hostAddr})",
-            probe.models.map(m ⇒ s"ID: ${m.id}, ver.${m.version}").toSeq
+            probe.models.map(m ⇒ s"${m.id}, v${m.version}").toSeq
         )
         
         tbl
@@ -843,7 +843,7 @@
         usrPropsOpt: Option[Map[String, String]],
         logEnable: Boolean,
         parent: Span = null): Unit = {
-        startScopedSpan("askProbe", parent, "srvReqId" → srvReqId, "usrId" → usr.id, "modelId" → mdlId, "txt" → txt) { span ⇒
+        startScopedSpan("askProbe", parent, "srvReqId" → srvReqId, "usrId" → usr.id, "mdlId" → mdlId, "txt" → txt) { span ⇒
             val userProps =
                 usrPropsOpt match {
                     case Some(props) ⇒
@@ -974,7 +974,7 @@
       */
     @throws[NCE]
     def clearConversation(usrId: Long, mdlId: String, parent: Span = null): Unit =
-        startScopedSpan("clearConversation", parent, "usrId" → usrId, "modelId" → mdlId) { span ⇒
+        startScopedSpan("clearConversation", parent, "usrId" → usrId, "mdlId" → mdlId) { span ⇒
             val msg = NCProbeMessage("S2P_CLEAR_CONV",
                 "usrId" → usrId,
                 "mdlId" → mdlId
@@ -995,7 +995,7 @@
      */
     @throws[NCE]
     def clearDialog(usrId: Long, mdlId: String, parent: Span = null): Unit =
-        startScopedSpan("clearDialog", parent, "usrId" → usrId, "modelId" → mdlId) { span ⇒
+        startScopedSpan("clearDialog", parent, "usrId" → usrId, "mdlId" → mdlId) { span ⇒
             val msg = NCProbeMessage("S2P_CLEAR_DLG",
                 "usrId" → usrId,
                 "mdlId" → mdlId
@@ -1014,7 +1014,7 @@
       * @param parent Optional parent span.
       */
     def getModel(mdlId: String, parent: Span = null): NCProbeModelMdo =
-        startScopedSpan("getModel", parent, "modelId" → mdlId) { _ ⇒
+        startScopedSpan("getModel", parent, "mdlId" → mdlId) { _ ⇒
             probes.synchronized {
                 mdls.getOrElse(mdlId, throw new NCE(s"Unknown model ID: $mdlId"))
             }
@@ -1027,7 +1027,7 @@
       * @return
       */
     def getModelInfo(mdlId: String, parent: Span = null): Future[java.util.Map[String, AnyRef]] =
-        startScopedSpan("getModelInfo", parent, "modelId" → mdlId) { _ ⇒
+        startScopedSpan("getModelInfo", parent, "mdlId" → mdlId) { _ ⇒
             getProbeForModelId(mdlId) match {
                 case Some(probe) ⇒
                     val msg = NCProbeMessage("S2P_MODEL_INFO", "mdlId" → mdlId)
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/proclog/NCProcessLogManager.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/proclog/NCProcessLogManager.scala
index b981a83..e7d7f90 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/proclog/NCProcessLogManager.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/proclog/NCProcessLogManager.scala
@@ -178,7 +178,7 @@
         data: String,
         parent: Span = null
     ): Unit =
-        startScopedSpan("newEntry", parent, "srvReqId" → srvReqId, "usrId" → usrId, "modelId" → mdlId) { span ⇒
+        startScopedSpan("newEntry", parent, "srvReqId" → srvReqId, "usrId" → usrId, "mdlId" → mdlId) { span ⇒
             val id = logSeq.incrementAndGet()
 
             logLock.acquire()
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/query/NCQueryManager.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/query/NCQueryManager.scala
index 81c7376..c92d2a4 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/query/NCQueryManager.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/query/NCQueryManager.scala
@@ -120,7 +120,7 @@
             "srvReqId" → srvReqId,
             "usrId" → usrId,
             "txt" → txt,
-            "modelId" → mdlId,
+            "mdlId" → mdlId,
             "enableLog" → enabledLog,
             "usrAgent" → usrAgent.orNull,
             "rmtAddr" → rmtAddr.orNull
@@ -164,7 +164,7 @@
             "srvReqId" → srvReqId,
             "usrId" → usrId,
             "txt" → txt,
-            "modelId" → mdlId,
+            "mdlId" → mdlId,
             "enableLog" → enabledLog,
             "usrAgent" → usrAgent.orNull,
             "rmtAddr" → rmtAddr.orNull) { span ⇒
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/sql/NCSqlManager.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/sql/NCSqlManager.scala
index f49cdde..062f8c5 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/sql/NCSqlManager.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/sql/NCSqlManager.scala
@@ -722,7 +722,7 @@
         rcvTstamp: Timestamp,
         data: String,
         parent: Span): Unit =
-        startScopedSpan("newProcessingLog", parent, "usrId" → id, "srvReqId" → srvReqId, "txt" → txt, "modelId" → mdlId) { _ ⇒
+        startScopedSpan("newProcessingLog", parent, "usrId" → id, "srvReqId" → srvReqId, "txt" → txt, "mdlId" → mdlId) { _ ⇒
             NCSql.insert(
                 """
                   |INSERT INTO proc_log (
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/sugsyn/NCSuggestSynonymManager.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/sugsyn/NCSuggestSynonymManager.scala
index 1e6cb90..d7f524e 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/server/sugsyn/NCSuggestSynonymManager.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/server/sugsyn/NCSuggestSynonymManager.scala
@@ -155,7 +155,7 @@
      * @return
      */
     def suggest(mdlId: String, minScoreOpt: Option[Double], parent: Span = null): Future[NCSuggestSynonymResult] =
-        startScopedSpan("inspect", parent, "modelId" → mdlId) { _ ⇒
+        startScopedSpan("inspect", parent, "mdlId" → mdlId) { _ ⇒
             val now = System.currentTimeMillis()
 
             val promise = Promise[NCSuggestSynonymResult]()