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

sergeykamov pushed a commit to branch NLPCRAFT-366
in repository 
https://gitbox.apache.org/repos/asf/incubator-nlpcraft-java-client.git

commit 552764cf866a67ef0fdbf69ca8cd3c473229a9fc
Author: Sergey Kamov <[email protected]>
AuthorDate: Wed Aug 4 13:08:01 2021 +0300

    WIP.
---
 pom.xml                                            |   8 +-
 .../java/org/apache/nlpcraft/client/NCClient.java  |   6 +
 .../java/org/apache/nlpcraft/client/NCElement.java |  43 ++++
 .../nlpcraft/client/NCElementSynonymsData.java}    |  37 +---
 .../org/apache/nlpcraft/client/NCModelInfo.java    |  94 ++++++++
 .../java/org/apache/nlpcraft/client/NCValue.java   |  23 ++
 .../apache/nlpcraft/client/impl/NCClientImpl.java  |  35 ++-
 .../nlpcraft/client/impl/beans/NCElementBean.java  |  87 ++++++++
 .../impl/beans/NCElementSynonymsDataBean.java      |  85 ++++++++
 .../client/impl/beans/NCModelInfoBean.java         | 242 +++++++++++++++++++++
 .../client/impl/beans/NCModelInfoResultBean.java}  |  32 +--
 .../nlpcraft/client/impl/beans/NCValueBean.java}   |  31 +--
 .../org/apache/nlpcraft/client/NCModelTest1.java   | 151 +++++++++++++
 .../client/{NCModelTest.java => NCModelTest2.java} |  20 +-
 .../nlpcraft/client/models/NCRestSpecModel.java    | 242 +++++++++++++++++++++
 .../nlpcraft/client/models/NCSpecModelAdapter.java |  65 +++++-
 16 files changed, 1106 insertions(+), 95 deletions(-)

diff --git a/pom.xml b/pom.xml
index 7937092..86320de 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,7 +29,7 @@
         <commons.validator.ver>1.7</commons.validator.ver>
         <gson.ver>2.8.6</gson.ver>
         <log4j.ver>2.14.0</log4j.ver>
-        <nlpcraft.ver>0.8.0</nlpcraft.ver>
+        <nlpcraft.ver>0.9.0</nlpcraft.ver>
         <junit.ver>5.7.0</junit.ver>
         <maven.compiler.version>3.8.0</maven.compiler.version>
         <maven.shade.plugin.ver>3.2.4</maven.shade.plugin.ver>
@@ -48,7 +48,7 @@
     <name>NLPCraft - Java Client</name>
     <groupId>org.apache.nlpcraft</groupId>
     <artifactId>java-client</artifactId>
-    <version>0.7.5</version>
+    <version>0.9.0</version>
     <url>https://nlpcraft.apache.org</url>
     <description>An open source API to convert natural language into 
actions.</description>
 
@@ -85,7 +85,7 @@
         
<connection>scm:git:ssh://[email protected]/apache/incubator-nlpcraft.git</connection>
         
<developerConnection>scm:git:ssh://[email protected]/apache/incubator-nlpcraft.git</developerConnection>
         <!-- Set actual tag name here -->
-        <tag>v0.7.5</tag>
+        <tag>v0.9.0</tag>
     </scm>
 
     <dependencies>
@@ -394,7 +394,7 @@
                                     ===========================================
                                 -->
                                 <!-- Reason: 'contextWordServer' should be 
started. -->
-                                <exclude>**/NCModelTest.*</exclude>
+                                <exclude>**/NCModelTest2.*</exclude>
                             </excludes>
                         </configuration>
                     </execution>
diff --git a/src/main/java/org/apache/nlpcraft/client/NCClient.java 
b/src/main/java/org/apache/nlpcraft/client/NCClient.java
index 3fbc0ca..91efd74 100644
--- a/src/main/java/org/apache/nlpcraft/client/NCClient.java
+++ b/src/main/java/org/apache/nlpcraft/client/NCClient.java
@@ -556,6 +556,12 @@ public interface NCClient {
      * @see <a href="https://nlpcraft.apache.org/tools/syn_tool.html";>Synonym 
suggestion tool</a>.
      */
     NCSuggestionData suggestSynonyms(String mdlId, Double minScore)  throws 
NCClientException, IOException;
+
+    // TODO:
+    NCElementSynonymsData getSynonyms(String mdlId, String elmId)  throws 
NCClientException, IOException;
+
+    // TODO:
+    NCModelInfo getModelInfo(String mdlId)  throws NCClientException, 
IOException;
     
     /**
      * Closes the client and signs out from the REST server. Any further calls 
to this client will result in
diff --git a/src/main/java/org/apache/nlpcraft/client/NCElement.java 
b/src/main/java/org/apache/nlpcraft/client/NCElement.java
new file mode 100644
index 0000000..f470092
--- /dev/null
+++ b/src/main/java/org/apache/nlpcraft/client/NCElement.java
@@ -0,0 +1,43 @@
+/*
+ * 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.client;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+// TODO: same as model NCElement without getValueLoader....
+public interface NCElement {
+    String getId();
+
+    List<String> getGroups();
+
+    Map<String, Object> getMetadata();
+
+    String getDescription();
+
+    List<NCValue> getValues();
+
+    String getParentId();
+
+    List<String> getSynonyms();
+
+    Optional<Boolean> isPermutateSynonyms();
+
+    Optional<Boolean> isSparse();
+}
diff --git 
a/src/test/java/org/apache/nlpcraft/client/models/NCSuggestionSpecModel.java 
b/src/main/java/org/apache/nlpcraft/client/NCElementSynonymsData.java
similarity index 50%
copy from 
src/test/java/org/apache/nlpcraft/client/models/NCSuggestionSpecModel.java
copy to src/main/java/org/apache/nlpcraft/client/NCElementSynonymsData.java
index c757ca1..668a27c 100644
--- a/src/test/java/org/apache/nlpcraft/client/models/NCSuggestionSpecModel.java
+++ b/src/main/java/org/apache/nlpcraft/client/NCElementSynonymsData.java
@@ -15,34 +15,21 @@
  * limitations under the License.
  */
 
-package org.apache.nlpcraft.client.models;
+package org.apache.nlpcraft.client;
 
-import org.apache.nlpcraft.model.NCElement;
-import org.apache.nlpcraft.model.NCIntent;
-import org.apache.nlpcraft.model.NCIntentSample;
-
-import java.util.Collections;
-import java.util.Set;
+import java.util.List;
+import java.util.Map;
 
 /**
- * Test model.
+ * TODO:
  */
-public class NCSuggestionSpecModel extends NCSpecModelAdapter {
-    public static final String MDL_ID = 
NCSuggestionSpecModel.class.getSimpleName();
-
-    @Override
-    public String getId() {
-        return MDL_ID;
-    }
-
-    @Override
-    public Set<NCElement> getElements() {
-        return Collections.singleton(mkElement( "test"));
-    }
+public interface NCElementSynonymsData {
+    int getSynonymsCnt();
+    int getSynonymsExpCnt();
+    long getSynonymsExpRatePct();
 
-    @NCIntentSample({"Tests passed well"})
-    @NCIntent("intent=intentId term~{tok_id() == 'test'}")
-    public org.apache.nlpcraft.model.NCResult onTest() {
-        return org.apache.nlpcraft.model.NCResult.text("OK");
-    }
+    List<String> getSynonyms();
+    List<String> getSynonymsExp();
+    Map<String, List<String>> getValues();
+    Map<String, List<String>> getValuesExp();
 }
diff --git a/src/main/java/org/apache/nlpcraft/client/NCModelInfo.java 
b/src/main/java/org/apache/nlpcraft/client/NCModelInfo.java
new file mode 100644
index 0000000..1c7b05c
--- /dev/null
+++ b/src/main/java/org/apache/nlpcraft/client/NCModelInfo.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.nlpcraft.client;
+
+import java.util.Map;
+import java.util.Set;
+
+// TODO: same as NCModelView without getParsers
+public interface NCModelInfo {
+    String getId();
+
+    String getName();
+
+    String getVersion();
+
+    String getDescription();
+
+    String getOrigin();
+
+    int getMaxUnknownWords();
+
+    int getMaxFreeWords();
+
+    int getMaxSuspiciousWords();
+
+    int getMinWords();
+
+    int getMaxWords();
+
+    int getMinTokens();
+
+    int getMaxTokens();
+
+    int getMinNonStopwords();
+
+    boolean isNonEnglishAllowed();
+
+    boolean isNotLatinCharsetAllowed();
+
+    boolean isSwearWordsAllowed();
+
+    boolean isNoNounsAllowed();
+
+    boolean isPermutateSynonyms();
+
+    boolean isDupSynonymsAllowed();
+
+    int getMaxTotalSynonyms();
+
+    boolean isNoUserTokensAllowed();
+
+    boolean isSparse();
+
+    Map<String, Object> getMetadata();
+
+    Set<String> getAdditionalStopWords();
+
+    Set<String> getExcludedStopWords();
+
+    Set<String> getSuspiciousWords();
+
+    Map<String, String> getMacros();
+
+    Set<NCElement> getElements();
+
+    Set<String> getEnabledBuiltInTokens();
+
+    Set<String> getAbstractTokens();
+
+    int getMaxElementSynonyms();
+
+    boolean isMaxSynonymsThresholdError();
+
+    long getConversationTimeout();
+
+    int getConversationDepth();
+
+    Map<String, Set<String>> getRestrictedCombinations();
+}
diff --git a/src/main/java/org/apache/nlpcraft/client/NCValue.java 
b/src/main/java/org/apache/nlpcraft/client/NCValue.java
new file mode 100644
index 0000000..953ae25
--- /dev/null
+++ b/src/main/java/org/apache/nlpcraft/client/NCValue.java
@@ -0,0 +1,23 @@
+/*
+ * 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.client;
+
+// TODO: same as model NCValue without synonyms
+public interface NCValue {
+    String getName();
+}
diff --git a/src/main/java/org/apache/nlpcraft/client/impl/NCClientImpl.java 
b/src/main/java/org/apache/nlpcraft/client/impl/NCClientImpl.java
index a9bef16..027156b 100644
--- a/src/main/java/org/apache/nlpcraft/client/impl/NCClientImpl.java
+++ b/src/main/java/org/apache/nlpcraft/client/impl/NCClientImpl.java
@@ -36,7 +36,9 @@ import org.apache.logging.log4j.Logger;
 import org.apache.nlpcraft.client.NCClient;
 import org.apache.nlpcraft.client.NCClientException;
 import org.apache.nlpcraft.client.NCCompany;
+import org.apache.nlpcraft.client.NCElementSynonymsData;
 import org.apache.nlpcraft.client.NCFeedback;
+import org.apache.nlpcraft.client.NCModelInfo;
 import org.apache.nlpcraft.client.NCNewCompany;
 import org.apache.nlpcraft.client.NCProbe;
 import org.apache.nlpcraft.client.NCResult;
@@ -47,9 +49,11 @@ import org.apache.nlpcraft.client.impl.beans.NCAskSyncBean;
 import org.apache.nlpcraft.client.impl.beans.NCCheckBean;
 import org.apache.nlpcraft.client.impl.beans.NCCompanyBean;
 import org.apache.nlpcraft.client.impl.beans.NCCompanyTokenResetBean;
+import org.apache.nlpcraft.client.impl.beans.NCElementSynonymsDataBean;
 import org.apache.nlpcraft.client.impl.beans.NCErrorMessageBean;
 import org.apache.nlpcraft.client.impl.beans.NCFeedbackAddBean;
 import org.apache.nlpcraft.client.impl.beans.NCFeedbackAllBean;
+import org.apache.nlpcraft.client.impl.beans.NCModelInfoResultBean;
 import org.apache.nlpcraft.client.impl.beans.NCProbesAllBean;
 import org.apache.nlpcraft.client.impl.beans.NCRequestStateBean;
 import org.apache.nlpcraft.client.impl.beans.NCSigninBean;
@@ -417,7 +421,7 @@ public class NCClientImpl implements NCClient {
 
                 if (code == 200)
                     return js;
-    
+
                 NCErrorMessageBean err;
                 
                 try {
@@ -426,7 +430,7 @@ public class NCClientImpl implements NCClient {
                 catch (Exception e1) {
                     throw new NCClientException(String.format("Unexpected 
server error [code=%d]", code));
                 }
-    
+
                 throw new NCClientException(err.getMessage(), err.getCode());
             };
             
@@ -1012,4 +1016,31 @@ public class NCClientImpl implements NCClient {
 
         return res.getResult();
     }
+
+    @Override
+    public NCElementSynonymsData getSynonyms(String mdlId, String elmId) 
throws NCClientException, IOException {
+        return checkAndExtract(
+            post(
+                "model/syns",
+                Pair.of("acsTok", acsTok),
+                Pair.of("mdlId", mdlId),
+                Pair.of("elmId", elmId)
+            ),
+            NCElementSynonymsDataBean.class
+        );
+    }
+
+    @Override
+    public NCModelInfo getModelInfo(String mdlId) throws NCClientException, 
IOException {
+        NCModelInfoResultBean res = checkAndExtract(
+            post(
+                "model/info",
+                Pair.of("acsTok", acsTok),
+                Pair.of("mdlId", mdlId)
+            ),
+            NCModelInfoResultBean.class
+        );
+
+        return res.getModel();
+    }
 }
diff --git 
a/src/main/java/org/apache/nlpcraft/client/impl/beans/NCElementBean.java 
b/src/main/java/org/apache/nlpcraft/client/impl/beans/NCElementBean.java
new file mode 100644
index 0000000..00f2391
--- /dev/null
+++ b/src/main/java/org/apache/nlpcraft/client/impl/beans/NCElementBean.java
@@ -0,0 +1,87 @@
+/*
+ * 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.client.impl.beans;
+
+import com.google.gson.annotations.SerializedName;
+import org.apache.nlpcraft.client.NCElement;
+import org.apache.nlpcraft.client.NCValue;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * REST bean.
+ */
+public class NCElementBean implements NCElement {
+    @SerializedName("id") private String id;
+    @SerializedName("groups") private List<String> groups;
+    @SerializedName("metadata") private Map<String, Object> metadata;
+    @SerializedName("description") private String description;
+    @SerializedName("values") private List<NCValueBean> values;
+    @SerializedName("parentId") private String parentId;
+    @SerializedName("synonyms") private List<String> synonyms;
+    @SerializedName("permutateSynonyms") private Optional<Boolean> 
permutateSynonyms;
+    @SerializedName("sparse") private Optional<Boolean> sparse;
+
+    @Override
+    public String getId() {
+        return id;
+    }
+
+    @Override
+    public List<String> getGroups() {
+        return groups;
+    }
+
+    @Override
+    public Map<String, Object> getMetadata() {
+        return metadata;
+    }
+
+    @Override
+    public String getDescription() {
+        return description;
+    }
+
+    @Override
+    public List<NCValue> getValues() {
+        return values != null ? new ArrayList<>(values) : null;
+    }
+
+    @Override
+    public String getParentId() {
+        return parentId;
+    }
+
+    @Override
+    public List<String> getSynonyms() {
+        return synonyms;
+    }
+
+    @Override
+    public Optional<Boolean> isPermutateSynonyms() {
+        return permutateSynonyms != null ? permutateSynonyms: Optional.empty();
+    }
+
+    @Override
+    public Optional<Boolean> isSparse() {
+        return sparse != null ? sparse: Optional.empty();
+    }
+}
diff --git 
a/src/main/java/org/apache/nlpcraft/client/impl/beans/NCElementSynonymsDataBean.java
 
b/src/main/java/org/apache/nlpcraft/client/impl/beans/NCElementSynonymsDataBean.java
new file mode 100644
index 0000000..c321acb
--- /dev/null
+++ 
b/src/main/java/org/apache/nlpcraft/client/impl/beans/NCElementSynonymsDataBean.java
@@ -0,0 +1,85 @@
+/*
+ * 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.client.impl.beans;
+
+import com.google.gson.annotations.SerializedName;
+import org.apache.nlpcraft.client.NCElementSynonymsData;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * REST bean.
+ */
+public class NCElementSynonymsDataBean extends NCStatusResponseBean implements 
NCElementSynonymsData {
+    @SerializedName("synonymsCnt")
+    private int synonymsCnt;
+
+    @SerializedName("synonymsExpCnt")
+    private int synonymsExpCnt;
+
+    @SerializedName("synonymsExpRatePct")
+    private long synonymsExpRatePct;
+
+    @SerializedName("synonyms")
+    private List<String> synonyms;
+
+    @SerializedName("synonymsExp")
+    private List<String> synonymsExp;
+
+    @SerializedName("values")
+    private Map<String, List<String>> values;
+
+    @SerializedName("valuesExp")
+    private Map<String, List<String>> valuesExp;
+
+    @Override
+    public int getSynonymsCnt() {
+        return synonymsCnt;
+    }
+
+    @Override
+    public int getSynonymsExpCnt() {
+        return synonymsExpCnt;
+    }
+
+    @Override
+    public long getSynonymsExpRatePct() {
+        return synonymsExpRatePct;
+    }
+
+    @Override
+    public List<String> getSynonyms() {
+        return synonyms;
+    }
+
+    @Override
+    public List<String> getSynonymsExp() {
+        return synonymsExp;
+    }
+
+    @Override
+    public Map<String, List<String>> getValues() {
+        return values;
+    }
+
+    @Override
+    public Map<String, List<String>> getValuesExp() {
+        return valuesExp;
+    }
+}
diff --git 
a/src/main/java/org/apache/nlpcraft/client/impl/beans/NCModelInfoBean.java 
b/src/main/java/org/apache/nlpcraft/client/impl/beans/NCModelInfoBean.java
new file mode 100644
index 0000000..1bafe80
--- /dev/null
+++ b/src/main/java/org/apache/nlpcraft/client/impl/beans/NCModelInfoBean.java
@@ -0,0 +1,242 @@
+/*
+ * 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.client.impl.beans;
+
+import com.google.gson.annotations.SerializedName;
+import org.apache.nlpcraft.client.NCModelInfo;
+import org.apache.nlpcraft.client.NCElement;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * REST bean.
+ */
+public class NCModelInfoBean implements NCModelInfo {
+    @SerializedName("id") private String id;
+    @SerializedName("name") private String name;
+    @SerializedName("version") private String version;
+    @SerializedName("description") private String description;
+    @SerializedName("origin") private String origin;
+    @SerializedName("maxUnknownWords") private int maxUnknownWords;
+    @SerializedName("maxFreeWords") private int maxFreeWords;
+    @SerializedName("maxSuspiciousWords") private int maxSuspiciousWords;
+    @SerializedName("minWords") private int minWords;
+    @SerializedName("maxWords") private int maxWords;
+    @SerializedName("minTokens") private int minTokens;
+    @SerializedName("maxTokens") private int maxTokens;
+    @SerializedName("minNonStopwords") private int minNonStopwords;
+    @SerializedName("nonEnglishAllowed") private boolean nonEnglishAllowed;
+    @SerializedName("notLatinCharsetAllowed") private boolean 
notLatinCharsetAllowed;
+    @SerializedName("swearWordsAllowed") private boolean swearWordsAllowed;
+    @SerializedName("noNounsAllowed") private boolean noNounsAllowed;
+    @SerializedName("permutateSynonyms") private boolean permutateSynonyms;
+    @SerializedName("dupSynonymsAllowed") private boolean dupSynonymsAllowed;
+    @SerializedName("maxTotalSynonyms") private int maxTotalSynonyms;
+    @SerializedName("noUserTokensAllowed") private boolean noUserTokensAllowed;
+    @SerializedName("sparse") private boolean sparse;
+    @SerializedName("metadata") private Map<String, Object> metadata;
+    @SerializedName("additionalStopWords") private Set<String> 
additionalStopWords;
+    @SerializedName("excludedStopWords") private Set<String> excludedStopWords;
+    @SerializedName("suspiciousWords") private Set<String> suspiciousWords;
+    @SerializedName("macros") private Map<String, String> macros;
+    @SerializedName("elements") private Set<NCElementBean> elements;
+    @SerializedName("enabledBuiltInTokens") private Set<String> 
enabledBuiltInTokens;
+    @SerializedName("abstractTokens") private Set<String> abstractTokens;
+    @SerializedName("maxElementSynonyms") private int maxElementSynonyms;
+    @SerializedName("maxSynonymsThresholdError") private boolean 
maxSynonymsThresholdError;
+    @SerializedName("conversationTimeout") private long conversationTimeout;
+    @SerializedName("conversationDepth") private int conversationDepth;
+    @SerializedName("restrictedCombinations") private Map<String, Set<String>> 
restrictedCombinations;
+
+    @Override
+    public String getId() {
+        return id;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String getVersion() {
+        return version;
+    }
+
+    @Override
+    public String getDescription() {
+        return description;
+    }
+
+    @Override
+    public String getOrigin() {
+        return origin;
+    }
+
+    @Override
+    public int getMaxUnknownWords() {
+        return maxUnknownWords;
+    }
+
+    @Override
+    public int getMaxFreeWords() {
+        return maxFreeWords;
+    }
+
+    @Override
+    public int getMaxSuspiciousWords() {
+        return maxSuspiciousWords;
+    }
+
+    @Override
+    public int getMinWords() {
+        return minWords;
+    }
+
+    @Override
+    public int getMaxWords() {
+        return maxWords;
+    }
+
+    @Override
+    public int getMinTokens() {
+        return minTokens;
+    }
+
+    @Override
+    public int getMaxTokens() {
+        return maxTokens;
+    }
+
+    @Override
+    public int getMinNonStopwords() {
+        return minNonStopwords;
+    }
+
+    @Override
+    public boolean isNonEnglishAllowed() {
+        return nonEnglishAllowed;
+    }
+
+    @Override
+    public boolean isNotLatinCharsetAllowed() {
+        return notLatinCharsetAllowed;
+    }
+
+    @Override
+    public boolean isSwearWordsAllowed() {
+        return swearWordsAllowed;
+    }
+
+    @Override
+    public boolean isNoNounsAllowed() {
+        return noNounsAllowed;
+    }
+
+    @Override
+    public boolean isPermutateSynonyms() {
+        return permutateSynonyms;
+    }
+
+    @Override
+    public boolean isDupSynonymsAllowed() {
+        return dupSynonymsAllowed;
+    }
+
+    @Override
+    public int getMaxTotalSynonyms() {
+        return maxTotalSynonyms;
+    }
+
+    @Override
+    public boolean isNoUserTokensAllowed() {
+        return noUserTokensAllowed;
+    }
+
+    @Override
+    public boolean isSparse() {
+        return sparse;
+    }
+
+    @Override
+    public Map<String, Object> getMetadata() {
+        return metadata;
+    }
+
+    @Override
+    public Set<String> getAdditionalStopWords() {
+        return additionalStopWords;
+    }
+
+    @Override
+    public Set<String> getExcludedStopWords() {
+        return excludedStopWords;
+    }
+
+    @Override
+    public Set<String> getSuspiciousWords() {
+        return suspiciousWords;
+    }
+
+    @Override
+    public Map<String, String> getMacros() {
+        return macros;
+    }
+
+    @Override
+    public Set<NCElement> getElements() {
+        return elements != null ? new HashSet<>(elements) : null;
+    }
+
+    @Override
+    public Set<String> getEnabledBuiltInTokens() {
+        return enabledBuiltInTokens;
+    }
+
+    @Override
+    public Set<String> getAbstractTokens() {
+        return abstractTokens;
+    }
+
+    @Override
+    public int getMaxElementSynonyms() {
+        return maxElementSynonyms;
+    }
+
+    @Override
+    public boolean isMaxSynonymsThresholdError() {
+        return maxSynonymsThresholdError;
+    }
+
+    @Override
+    public long getConversationTimeout() {
+        return conversationTimeout;
+    }
+
+    @Override
+    public int getConversationDepth() {
+        return conversationDepth;
+    }
+
+    @Override
+    public Map<String, Set<String>> getRestrictedCombinations() {
+        return restrictedCombinations;
+    }
+}
diff --git 
a/src/test/java/org/apache/nlpcraft/client/models/NCSuggestionSpecModel.java 
b/src/main/java/org/apache/nlpcraft/client/impl/beans/NCModelInfoResultBean.java
similarity index 50%
copy from 
src/test/java/org/apache/nlpcraft/client/models/NCSuggestionSpecModel.java
copy to 
src/main/java/org/apache/nlpcraft/client/impl/beans/NCModelInfoResultBean.java
index c757ca1..0750e9d 100644
--- a/src/test/java/org/apache/nlpcraft/client/models/NCSuggestionSpecModel.java
+++ 
b/src/main/java/org/apache/nlpcraft/client/impl/beans/NCModelInfoResultBean.java
@@ -15,34 +15,18 @@
  * limitations under the License.
  */
 
-package org.apache.nlpcraft.client.models;
+package org.apache.nlpcraft.client.impl.beans;
 
-import org.apache.nlpcraft.model.NCElement;
-import org.apache.nlpcraft.model.NCIntent;
-import org.apache.nlpcraft.model.NCIntentSample;
-
-import java.util.Collections;
-import java.util.Set;
+import com.google.gson.annotations.SerializedName;
 
 /**
- * Test model.
+ * REST bean.
  */
-public class NCSuggestionSpecModel extends NCSpecModelAdapter {
-    public static final String MDL_ID = 
NCSuggestionSpecModel.class.getSimpleName();
-
-    @Override
-    public String getId() {
-        return MDL_ID;
-    }
-
-    @Override
-    public Set<NCElement> getElements() {
-        return Collections.singleton(mkElement( "test"));
-    }
+public class NCModelInfoResultBean extends NCStatusResponseBean {
+    @SerializedName("model")
+    private NCModelInfoBean model;
 
-    @NCIntentSample({"Tests passed well"})
-    @NCIntent("intent=intentId term~{tok_id() == 'test'}")
-    public org.apache.nlpcraft.model.NCResult onTest() {
-        return org.apache.nlpcraft.model.NCResult.text("OK");
+    public NCModelInfoBean getModel() {
+        return model;
     }
 }
diff --git 
a/src/test/java/org/apache/nlpcraft/client/models/NCSuggestionSpecModel.java 
b/src/main/java/org/apache/nlpcraft/client/impl/beans/NCValueBean.java
similarity index 51%
rename from 
src/test/java/org/apache/nlpcraft/client/models/NCSuggestionSpecModel.java
rename to src/main/java/org/apache/nlpcraft/client/impl/beans/NCValueBean.java
index c757ca1..7eb7525 100644
--- a/src/test/java/org/apache/nlpcraft/client/models/NCSuggestionSpecModel.java
+++ b/src/main/java/org/apache/nlpcraft/client/impl/beans/NCValueBean.java
@@ -15,34 +15,19 @@
  * limitations under the License.
  */
 
-package org.apache.nlpcraft.client.models;
+package org.apache.nlpcraft.client.impl.beans;
 
-import org.apache.nlpcraft.model.NCElement;
-import org.apache.nlpcraft.model.NCIntent;
-import org.apache.nlpcraft.model.NCIntentSample;
-
-import java.util.Collections;
-import java.util.Set;
+import com.google.gson.annotations.SerializedName;
+import org.apache.nlpcraft.client.NCValue;
 
 /**
- * Test model.
+ * REST bean.
  */
-public class NCSuggestionSpecModel extends NCSpecModelAdapter {
-    public static final String MDL_ID = 
NCSuggestionSpecModel.class.getSimpleName();
-
-    @Override
-    public String getId() {
-        return MDL_ID;
-    }
+public class NCValueBean implements NCValue {
+    @SerializedName("name") private String name;
 
     @Override
-    public Set<NCElement> getElements() {
-        return Collections.singleton(mkElement( "test"));
-    }
-
-    @NCIntentSample({"Tests passed well"})
-    @NCIntent("intent=intentId term~{tok_id() == 'test'}")
-    public org.apache.nlpcraft.model.NCResult onTest() {
-        return org.apache.nlpcraft.model.NCResult.text("OK");
+    public String getName() {
+        return name;
     }
 }
diff --git a/src/test/java/org/apache/nlpcraft/client/NCModelTest1.java 
b/src/test/java/org/apache/nlpcraft/client/NCModelTest1.java
new file mode 100644
index 0000000..732c92b
--- /dev/null
+++ b/src/test/java/org/apache/nlpcraft/client/NCModelTest1.java
@@ -0,0 +1,151 @@
+/*
+ * 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.client;
+
+import org.apache.nlpcraft.client.models.NCRestSpecModel;
+import org.apache.nlpcraft.model.NCModel;
+import org.junit.jupiter.api.Test;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.apache.nlpcraft.client.models.NCRestSpecModel.MDL_ID;
+import static org.apache.nlpcraft.client.models.NCRestSpecModel.VAL_ELEM_ID;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * REST client test. Methods `model/syns`,`model/info`.
+ */
+class NCModelTest1 extends NCTestAdapter {
+    @Override
+    Optional<Class<? extends NCModel>> getModelClass() {
+        return Optional.of(NCRestSpecModel.class);
+    }
+
+    @Test
+    void testElementSynonyms() throws Exception {
+        NCElementSynonymsData s = admCli.getSynonyms(MDL_ID, VAL_ELEM_ID);
+
+        assertTrue(s.getSynonymsCnt() > 0);
+        assertTrue(s.getSynonymsExpCnt() > 0);
+        assertTrue(s.getSynonymsExpRatePct() > 0);
+
+        assertTrue(s.getSynonyms() != null && !s.getSynonyms().isEmpty());
+        assertTrue(s.getSynonymsExp() != null && 
!s.getSynonymsExp().isEmpty());
+        assertTrue(s.getValues() != null && !s.getValues().isEmpty());
+        assertTrue(s.getValuesExp() != null && !s.getValuesExp().isEmpty());
+    }
+
+    /**
+     * @throws Exception
+     */
+    @Test
+    void testModelInfo() throws Exception {
+        NCRestSpecModel mdl1 = new NCRestSpecModel();
+
+        // Checked model values.
+        assert mdl1.getElements().stream().anyMatch(p -> p.getValues() != null 
&& !p.getValues().isEmpty());
+
+        NCModelInfo mdl2 = admCli.getModelInfo(MDL_ID);
+
+        assertEquals(mdl1.getId(), mdl2.getId());
+        assertEquals(mdl1.getName(), mdl2.getName());
+        assertEquals(mdl1.getDescription(), mdl2.getDescription());
+        assertEquals(mdl1.getVersion(), mdl2.getVersion());
+        assertEquals(mdl1.getOrigin(), mdl2.getOrigin());
+        assertEquals(mdl1.getMaxUnknownWords(), mdl2.getMaxUnknownWords());
+        assertEquals(mdl1.getMaxFreeWords(), mdl2.getMaxFreeWords());
+        assertEquals(mdl1.getMaxSuspiciousWords(), 
mdl2.getMaxSuspiciousWords());
+        assertEquals(mdl1.getMinWords(), mdl2.getMinWords());
+        assertEquals(mdl1.getMaxWords(), mdl2.getMaxWords());
+        assertEquals(mdl1.getMinTokens(), mdl2.getMinTokens());
+        assertEquals(mdl1.getMaxTokens(), mdl2.getMaxTokens());
+        assertEquals(mdl1.getMinNonStopwords(), mdl2.getMinNonStopwords());
+        assertEquals(mdl1.isNonEnglishAllowed(), mdl2.isNonEnglishAllowed());
+        assertEquals(mdl1.isNotLatinCharsetAllowed(), 
mdl2.isNotLatinCharsetAllowed());
+        assertEquals(mdl1.isSwearWordsAllowed(), mdl2.isSwearWordsAllowed());
+        assertEquals(mdl1.isNoNounsAllowed(), mdl2.isNoNounsAllowed());
+        assertEquals(mdl1.isPermutateSynonyms(), mdl2.isPermutateSynonyms());
+        assertEquals(mdl1.isDupSynonymsAllowed(), mdl2.isDupSynonymsAllowed());
+        assertEquals(mdl1.getMaxTotalSynonyms(), mdl2.getMaxTotalSynonyms());
+        assertEquals(mdl1.isNoUserTokensAllowed(), 
mdl2.isNoUserTokensAllowed());
+        assertEquals(mdl1.isSparse(), mdl2.isSparse());
+        assertEquals(mdl1.getMetadata(), mdl2.getMetadata());
+        assertEquals(mdl1.getAdditionalStopWords(), 
mdl2.getAdditionalStopWords());
+        assertEquals(mdl1.getExcludedStopWords(), mdl2.getExcludedStopWords());
+        assertEquals(mdl1.getSuspiciousWords(), mdl2.getSuspiciousWords());
+        assertEquals(mdl1.getMacros(), mdl2.getMacros());
+        assertEquals(mdl1.getEnabledBuiltInTokens(), 
mdl2.getEnabledBuiltInTokens());
+        assertEquals(mdl1.getAbstractTokens(), mdl2.getAbstractTokens());
+        assertEquals(mdl1.getMaxElementSynonyms(), 
mdl2.getMaxElementSynonyms());
+        assertEquals(mdl1.isMaxSynonymsThresholdError(), 
mdl2.isMaxSynonymsThresholdError());
+        assertEquals(mdl1.getConversationTimeout(), 
mdl2.getConversationTimeout());
+        assertEquals(mdl1.getConversationDepth(), mdl2.getConversationDepth());
+        assertEquals(mdl1.getRestrictedCombinations(), 
mdl2.getRestrictedCombinations());
+
+        Set<org.apache.nlpcraft.model.NCElement> elems1 = mdl1.getElements();
+        Set<org.apache.nlpcraft.client.NCElement> elems2 = mdl2.getElements();
+
+        assertEquals(elems1.size(), elems2.size());
+
+        int n = elems1.size();
+
+        List<org.apache.nlpcraft.model.NCElement> elemList1 =
+            
elems1.stream().sorted(Comparator.comparing(org.apache.nlpcraft.model.NCElement::getId)).collect(Collectors.toList());
+
+        List<org.apache.nlpcraft.client.NCElement> elemList2 =
+            
elems2.stream().sorted(Comparator.comparing(org.apache.nlpcraft.client.NCElement::getId)).collect(Collectors.toList());
+
+        for (int i = 0; i < n; i++) {
+            org.apache.nlpcraft.model.NCElement e1 = elemList1.get(i);
+            org.apache.nlpcraft.client.NCElement e2 = elemList2.get(i);
+
+            assertEquals(e1.getId(), e2.getId());
+            assertEquals(e1.getGroups(), e2.getGroups());
+            assertEquals(e1.getMetadata(), e2.getMetadata());
+            assertEquals(e1.getDescription(), e2.getDescription());
+            assertEquals(e1.getParentId(), e2.getParentId());
+            // TODO ?
+            assertEquals(e1.getSynonyms(), e2.getSynonyms());
+            assertEquals(e1.isPermutateSynonyms(), e2.isPermutateSynonyms());
+            assertEquals(e1.isSparse(), e2.isSparse());
+
+            List<org.apache.nlpcraft.model.NCValue> values1 = e1.getValues();
+            List<org.apache.nlpcraft.client.NCValue> values2 = e2.getValues();
+
+            int n1 = values1 == null ? 0 : values1.size();
+            int n2 = values2 == null ? 0 : values2.size();
+
+            assertEquals(n1, n2);
+
+            for (int j = 0; j < n1; j++) {
+                org.apache.nlpcraft.model.NCValue v1 = values1.get(i);
+                org.apache.nlpcraft.client.NCValue v2 = values2.get(i);
+
+                assertEquals(v1.getName(), v2.getName());
+
+                // TODO ?
+                //assertEquals(v1.getSynonyms(), v2.getSynonyms());
+            }
+        }
+    }
+}
diff --git a/src/test/java/org/apache/nlpcraft/client/NCModelTest.java 
b/src/test/java/org/apache/nlpcraft/client/NCModelTest2.java
similarity index 75%
rename from src/test/java/org/apache/nlpcraft/client/NCModelTest.java
rename to src/test/java/org/apache/nlpcraft/client/NCModelTest2.java
index de94337..b02d2d7 100644
--- a/src/test/java/org/apache/nlpcraft/client/NCModelTest.java
+++ b/src/test/java/org/apache/nlpcraft/client/NCModelTest2.java
@@ -17,8 +17,7 @@
 
 package org.apache.nlpcraft.client;
 
-import org.apache.nlpcraft.client.models.NCSuggestionSpecModel;
-import org.apache.nlpcraft.model.NCModel;
+import org.apache.nlpcraft.client.models.NCRestSpecModel;
 import org.junit.jupiter.api.Test;
 
 import java.util.Collection;
@@ -26,24 +25,19 @@ import java.util.List;
 import java.util.Optional;
 import java.util.stream.Collectors;
 
-import static org.apache.nlpcraft.client.models.NCSuggestionSpecModel.MDL_ID;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.apache.nlpcraft.client.models.NCRestSpecModel.MDL_ID;
+import static org.junit.jupiter.api.Assertions.*;
 
 /**
- * REST client test. Methods `model/sugsyn`.
+ * REST client test. Methods `model/sugsyn`. Required started 'ctxword' server.
  */
-class NCModelTest extends NCTestAdapter {
+class NCModelTest2 extends NCTestAdapter {
     @Override
-    Optional<Class<? extends NCModel>> getModelClass() {
-        return Optional.of(NCSuggestionSpecModel.class);
+    Optional<Class<? extends org.apache.nlpcraft.model.NCModel>> 
getModelClass() {
+        return Optional.of(NCRestSpecModel.class);
     }
 
     /**
-     *
      * @param s
      * @param minScore
      * @throws Exception
diff --git 
a/src/test/java/org/apache/nlpcraft/client/models/NCRestSpecModel.java 
b/src/test/java/org/apache/nlpcraft/client/models/NCRestSpecModel.java
new file mode 100644
index 0000000..da3ee5a
--- /dev/null
+++ b/src/test/java/org/apache/nlpcraft/client/models/NCRestSpecModel.java
@@ -0,0 +1,242 @@
+/*
+ * 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.client.models;
+
+import org.apache.nlpcraft.model.NCCustomParser;
+import org.apache.nlpcraft.model.NCElement;
+import org.apache.nlpcraft.model.NCIntent;
+import org.apache.nlpcraft.model.NCIntentSample;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Test model for requests: `model/sugsyn`, `model/syns`,`model/info`.
+ */
+public class NCRestSpecModel extends NCSpecModelAdapter {
+    public static final String MDL_ID = NCRestSpecModel.class.getSimpleName();
+    public static final String VAL_ELEM_ID = "valTest";
+
+    private static Set<String> mkSet(String ... data) {
+        return new HashSet<>(Arrays.asList(data));
+    }
+
+    @Override
+    public String getDescription() {
+        return "some desc";
+    }
+
+    @Override
+    public String getOrigin() {
+        return "some origin";
+    }
+
+    @Override
+    public int getMaxUnknownWords() {
+        return 101;
+    }
+
+    @Override
+    public int getMaxFreeWords() {
+        return 22;
+    }
+
+    @Override
+    public int getMaxSuspiciousWords() {
+        return 23;
+    }
+
+    @Override
+    public int getMinWords() {
+        return 2;
+    }
+
+    @Override
+    public int getMaxWords() {
+        return 100;
+    }
+
+    @Override
+    public int getMinTokens() {
+        return 2;
+    }
+
+    @Override
+    public int getMaxTokens() {
+        return 12;
+    }
+
+    @Override
+    public int getMinNonStopwords() {
+        return 3;
+    }
+
+    @Override
+    public boolean isNonEnglishAllowed() {
+        return true;
+    }
+
+    @Override
+    public boolean isNotLatinCharsetAllowed() {
+        return true;
+    }
+
+    @Override
+    public boolean isSwearWordsAllowed() {
+        return true;
+    }
+
+    @Override
+    public boolean isNoNounsAllowed() {
+        return true;
+    }
+
+    @Override
+    public boolean isPermutateSynonyms() {
+        return true;
+    }
+
+    @Override
+    public boolean isDupSynonymsAllowed() {
+        return true;
+    }
+
+    @Override
+    public int getMaxTotalSynonyms() {
+        return 10101;
+    }
+
+    @Override
+    public boolean isNoUserTokensAllowed() {
+        return true;
+    }
+
+    @Override
+    public boolean isSparse() {
+        return true;
+    }
+
+    @Override
+    public Map<String, Object> getMetadata() {
+        Map<String, Object> m = new HashMap<>();
+
+        m.put("k1", 12.12);
+        m.put("k2", "word");
+
+        return m;
+    }
+
+    @Override
+    public Set<String> getAdditionalStopWords() {
+        return mkSet("a", "b");
+    }
+
+    @Override
+    public Set<String> getExcludedStopWords() {
+        return mkSet("x", "y");
+    }
+
+    @Override
+    public Set<String> getSuspiciousWords() {
+        return mkSet("f", "h", "h");
+    }
+
+    @Override
+    public Map<String, String> getMacros() {
+        Map<String, String> m = new HashMap<>();
+
+        m.put("<A>", "{a|_}");
+
+        return m;
+    }
+
+    @Override
+    public List<NCCustomParser> getParsers() {
+        return super.getParsers();
+    }
+
+    @Override
+    public Set<String> getEnabledBuiltInTokens() {
+        return mkSet("nlpcraft:limit", "nlpcraft:num");
+    }
+
+    @Override
+    public Set<String> getAbstractTokens() {
+        return mkSet(VAL_ELEM_ID);
+    }
+
+    @Override
+    public int getMaxElementSynonyms() {
+        return 123;
+    }
+
+    @Override
+    public boolean isMaxSynonymsThresholdError() {
+        return true;
+    }
+
+    @Override
+    public long getConversationTimeout() {
+        return 12345;
+    }
+
+    @Override
+    public int getConversationDepth() {
+        return 3;
+    }
+
+    @Override
+    public Map<String, Set<String>> getRestrictedCombinations() {
+        Map<String, Set<String>> m = new HashMap<>();
+
+        m.put("nlpcraft:limit", mkSet("valTest"));
+
+        return m;
+    }
+
+    @Override
+    public String getId() {
+        return MDL_ID;
+    }
+
+    @Override
+    public Set<NCElement> getElements() {
+        Set<NCElement> set = new HashSet<>();
+
+        set.add(mkElement( "test"));
+
+        Map<String, List<String>> vals = new HashMap<>();
+
+        vals.put("v1", List.of("v11", "v12"));
+        vals.put("v2", List.of("v21", "v22"));
+
+        set.add(mkElement(VAL_ELEM_ID, List.of("vt1", "vt2"), vals));
+
+        return set;
+    }
+
+    @NCIntentSample({"Tests passed well"})
+    @NCIntent("intent=intentId term~{tok_id() == 'test'}")
+    public org.apache.nlpcraft.model.NCResult onTest() {
+        return org.apache.nlpcraft.model.NCResult.text("OK");
+    }
+}
diff --git 
a/src/test/java/org/apache/nlpcraft/client/models/NCSpecModelAdapter.java 
b/src/test/java/org/apache/nlpcraft/client/models/NCSpecModelAdapter.java
index 8816a9b..67a8ff4 100644
--- a/src/test/java/org/apache/nlpcraft/client/models/NCSpecModelAdapter.java
+++ b/src/test/java/org/apache/nlpcraft/client/models/NCSpecModelAdapter.java
@@ -19,10 +19,13 @@ package org.apache.nlpcraft.client.models;
 
 import org.apache.nlpcraft.model.NCElement;
 import org.apache.nlpcraft.model.NCModel;
+import org.apache.nlpcraft.model.NCValue;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * Test model adapter.
@@ -38,6 +41,26 @@ abstract class NCSpecModelAdapter implements NCModel {
         return "1.0.0";
     }
 
+    /**
+     *
+     * @param id
+     * @param syns
+     * @return
+     */
+    private static List<String> mkSynonyms(String id, List<String> syns) {
+        List<String> l = new ArrayList<>(syns);
+
+        l.add(id);
+
+        return l;
+    }
+
+    /**
+     *
+     * @param id
+     * @param syns
+     * @return
+     */
     protected NCElement mkElement(String id, String... syns) {
         return new NCElement() {
             @Override
@@ -47,12 +70,46 @@ abstract class NCSpecModelAdapter implements NCModel {
 
             @Override
             public List<String> getSynonyms() {
-                List<String> l = new ArrayList<>();
+                return mkSynonyms(id, Arrays.asList(syns));
+            }
+        };
+    }
+
+    /**
+     *
+     * @param id
+     * @param syns
+     * @param vals
+     * @return
+     */
+    protected NCElement mkElement(String id, List<String> syns, Map<String, 
List<String>> vals) {
+        return new NCElement() {
+            @Override
+            public String getId() {
+                return id;
+            }
+
+            @Override
+            public List<String> getSynonyms() {
+                return mkSynonyms(id, syns);
+            }
 
-                l.add(id);
-                l.addAll(Arrays.asList(syns));
+            @Override
+            public List<NCValue> getValues() {
+                return
+                    vals.entrySet().stream().map(p ->
+                        new NCValue() {
+                            @Override
+                            public String getName() {
+                                return p.getKey();
+                            }
 
-                return l;
+                            @Override
+                            public List<String> getSynonyms() {
+                                return p.getValue();
+                            }
+                        }
+                    ).collect(Collectors.toList());
             }
         };
     }

Reply via email to