You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nlpcraft.apache.org by se...@apache.org on 2021/12/09 10:34:49 UTC

[incubator-nlpcraft] 01/01: WIP.

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

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

commit 2e0298dfd3f8c0e1f441da428a0de8140d055a0d
Author: Sergey Kamov <sk...@gmail.com>
AuthorDate: Thu Dec 9 13:34:11 2021 +0300

    WIP.
---
 .../scala/org/apache/nlpcraft/NCModelClient.java   |   8 +-
 .../org/apache/nlpcraft/NCModelConfigAdapter.java  |  43 +++++--
 .../enrichers/entity/NCFileUserEntityParser.scala} |  50 ++------
 .../enrichers/entity/NCUserEntityParser.scala}     |  52 ++------
 .../opennlp/NCOpenNlpDateEntityParser.scala}       |  45 +------
 .../opennlp/NCOpenNlpLocationEntityParser.scala}   |  45 +------
 .../opennlp/NCOpenNlpMoneyEntityParser.scala}      |  45 +------
 .../NCOpenNlpOrganizationEntityParser.scala}       |  45 +------
 .../opennlp/NCOpenNlpPercentageEntityParser.scala} |  45 +------
 .../opennlp/NCOpenNlpPersonEntityParser.scala}     |  45 +------
 .../opennlp/NCOpenNlpTimeEntityParser.scala}       |  45 +------
 .../token/NCEnDictionaryTokenEnricher.scala}       |  45 +------
 .../enrichers/token/NCEnQuotesTokenEnricher.scala} |  45 +------
 .../token/NCEnSwearWordsTokenEnricher.scala}       |  45 +------
 .../tokenizers/NCEnTokenParser.scala}              |  45 +------
 .../apache/nlpcraft/alarm/LightSwitchModel.java    |  73 +++++++++++
 .../nlpcraft/alarm/LightSwitchModelTest.java       | 137 +++++++++++++++++++++
 .../nlpcraft/alarm/LightSwitchModelTest2.java      |  75 +++++++++++
 nlpcraft/src/test/resources/lightswitch_model.json |  67 ++++++++++
 nlpcraft/src/test/resources/lightswitch_model.yaml |  28 +++++
 20 files changed, 497 insertions(+), 531 deletions(-)

diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelClient.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelClient.java
index 83b73ec..ba96d60 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelClient.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelClient.java
@@ -42,7 +42,7 @@ public class NCModelClient {
      * @return
      * @throws NCException
      */
-    CompletableFuture<NCResult> ask(String txt, Map<String, Object> data, String usrId) {
+    public CompletableFuture<NCResult> ask(String txt, Map<String, Object> data, String usrId) {
         return null; // TODO
     }
 
@@ -54,7 +54,7 @@ public class NCModelClient {
      * @return
      * @throws NCException
      */
-    NCResult askSync(String txt, Map<String, Object> data, String usrId) {
+    public NCResult askSync(String txt, Map<String, Object> data, String usrId) {
         return null; // TODO
     }
 
@@ -63,7 +63,7 @@ public class NCModelClient {
      * @param usrId
      * @throws NCException
      */
-    void clearConversation(String usrId) {
+    public void clearConversation(String usrId) {
         // TODO
     }
 
@@ -72,7 +72,7 @@ public class NCModelClient {
      * @param usrId
      * @throws NCException
      */
-    void clearDialog(String usrId) {
+    public void clearDialog(String usrId) {
         // TODO
     }
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
index e9d3b2f..8ca392c 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
@@ -22,39 +22,68 @@ import java.util.*;
 /**
  *
  */
+// TODO: validation for constructor and all setters.
 public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
+    private final String id;
+    private final String name;
+    private final String version;
+    private final NCTokenParser tokParser;
+
+    private List<NCTokenEnricher> tokenEnrichers;
+    private List<NCEntityEnricher> entityEnrichers;
+    private List<NCEntityParser> entityParsers;
+
+    public NCModelConfigAdapter(String id, String name, String version, NCTokenParser tokParser) {
+        this.id = id;
+        this.name = name;
+        this.version = version;
+        this.tokParser = tokParser;
+    }
+
     @Override
     public String getId() {
-        return null; // TODO
+        return id;
     }
 
     @Override
     public String getName() {
-        return null; // TODO
+        return name;
     }
 
     @Override
     public String getVersion() {
-        return null; // TODO
+        return version;
     }
 
     @Override
     public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
+        return tokenEnrichers;
     }
 
     @Override
     public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
+        return entityEnrichers;
     }
 
     @Override
     public NCTokenParser getTokenParser() {
-        return null; // TODO
+        return tokParser;
     }
 
     @Override
     public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
+        return entityParsers;
+    }
+
+    public void setTokenEnrichers(List<NCTokenEnricher> tokenEnrichers) {
+        this.tokenEnrichers = tokenEnrichers;
+    }
+
+    public void setEntityEnrichers(List<NCEntityEnricher> entityEnrichers) {
+        this.entityEnrichers = entityEnrichers;
+    }
+
+    public void setEntityParsers(List<NCEntityParser> entityParsers) {
+        this.entityParsers = entityParsers;
     }
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/NCFileUserEntityParser.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/NCFileUserEntityParser.scala
index e9d3b2f..2c44e25 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/NCFileUserEntityParser.scala
@@ -14,47 +14,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.enrichers.entity
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.*
 
-import java.util.*;
+import java.io.File
+import java.util
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+// File with 3 sections: Look at NCUserEntityParser
+// Element ID / Map element properties (parent, group, etc)
+// Macros ID / Macros body.
+// Element ID / Synonyms list, based on words and macros.
+class NCFileUserEntityParser(file: File) extends NCEntityParser {
+    override def parse(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): util.List[NCEntity] = ???
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/NCUserEntityParser.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/NCUserEntityParser.scala
index e9d3b2f..a362366 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/NCUserEntityParser.scala
@@ -14,47 +14,19 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.enrichers.entity
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.*
 
-import java.util.*;
+import java.util
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+class NCUserEntityParser(
+    // Element ID / Map element properties (parent, group, etc)
+    elementsDesc: util.Map[String, util.Map[String, String]],
+    // Macros ID / Macros body.
+    macros: util.Map[String, String],
+    // Element ID / Synonyms list, based on words and macros.
+    synonyms: util.Map[String, util.List[String]]
+) extends NCEntityParser {
+    override def parse(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): util.List[NCEntity] = ???
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpDateEntityParser.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpDateEntityParser.scala
index e9d3b2f..5bb1d87 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpDateEntityParser.scala
@@ -14,47 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.enrichers.entity.opennlp
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.{NCEntity, NCEntityParser, NCModelConfig, NCRequest, NCToken}
 
-import java.util.*;
+import java.util
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+class NCOpenNlpDateEntityParser extends NCEntityParser {
+    override def parse(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): util.List[NCEntity] = ???
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpLocationEntityParser.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpLocationEntityParser.scala
index e9d3b2f..efd9471 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpLocationEntityParser.scala
@@ -14,47 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.enrichers.entity.opennlp
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.*
 
-import java.util.*;
+import java.util
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+class NCOpenNlpLocationEntityParser extends NCEntityParser {
+    override def parse(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): util.List[NCEntity] = ???
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpMoneyEntityParser.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpMoneyEntityParser.scala
index e9d3b2f..18378e0 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpMoneyEntityParser.scala
@@ -14,47 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.enrichers.entity.opennlp
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.*
 
-import java.util.*;
+import java.util
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+class NCOpenNlpMoneyEntityParser extends NCEntityParser {
+    override def parse(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): util.List[NCEntity] = ???
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpOrganizationEntityParser.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpOrganizationEntityParser.scala
index e9d3b2f..560eb88 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpOrganizationEntityParser.scala
@@ -14,47 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.enrichers.entity.opennlp
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.*
 
-import java.util.*;
+import java.util
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+class NCOpenNlpOrganizationEntityParser extends NCEntityParser {
+    override def parse(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): util.List[NCEntity] = ???
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpPercentageEntityParser.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpPercentageEntityParser.scala
index e9d3b2f..ecc1bd6 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpPercentageEntityParser.scala
@@ -14,47 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.enrichers.entity.opennlp
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.*
 
-import java.util.*;
+import java.util
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+class NCOpenNlpPercentageEntityParser extends NCEntityParser {
+    override def parse(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): util.List[NCEntity] = ???
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpPersonEntityParser.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpPersonEntityParser.scala
index e9d3b2f..2b4e2ef 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpPersonEntityParser.scala
@@ -14,47 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.enrichers.entity.opennlp
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.*
 
-import java.util.*;
+import java.util
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+class NCOpenNlpPersonEntityParser extends NCEntityParser {
+    override def parse(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): util.List[NCEntity] = ???
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpTimeEntityParser.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpTimeEntityParser.scala
index e9d3b2f..e71870b 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/entity/opennlp/NCOpenNlpTimeEntityParser.scala
@@ -14,47 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.enrichers.entity.opennlp
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.*
 
-import java.util.*;
+import java.util
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+class NCOpenNlpTimeEntityParser extends NCEntityParser {
+    override def parse(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): util.List[NCEntity] = ???
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/token/NCEnDictionaryTokenEnricher.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/token/NCEnDictionaryTokenEnricher.scala
index e9d3b2f..53849a5 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/token/NCEnDictionaryTokenEnricher.scala
@@ -14,47 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.enrichers.token
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.{NCModelConfig, NCRequest, NCToken, NCTokenEnricher}
 
-import java.util.*;
+import java.util
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+class NCEnDictionaryTokenEnricher extends NCTokenEnricher {
+    override def enrich(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): Unit = ???
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/token/NCEnQuotesTokenEnricher.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/token/NCEnQuotesTokenEnricher.scala
index e9d3b2f..671de22 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/token/NCEnQuotesTokenEnricher.scala
@@ -14,47 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.enrichers.token
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.{NCModelConfig, NCRequest, NCToken, NCTokenEnricher}
 
-import java.util.*;
+import java.util
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+class NCEnQuotesTokenEnricher extends NCTokenEnricher {
+    override def enrich(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): Unit = ???
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/token/NCEnSwearWordsTokenEnricher.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/token/NCEnSwearWordsTokenEnricher.scala
index e9d3b2f..834d6fb 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/enrichers/token/NCEnSwearWordsTokenEnricher.scala
@@ -14,47 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.enrichers.token
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.{NCModelConfig, NCRequest, NCToken, NCTokenEnricher}
 
-import java.util.*;
+import java.util
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+class NCEnSwearWordsTokenEnricher extends NCTokenEnricher {
+    override def enrich(req: NCRequest, cfg: NCModelConfig, toks: util.List[NCToken]): Unit = ???
 }
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/tokenizers/NCEnTokenParser.scala
similarity index 50%
copy from nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
copy to nlpcraft/src/main/scala/org/apache/nlpcraft/impl/tokenizers/NCEnTokenParser.scala
index e9d3b2f..cc840a7 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/NCModelConfigAdapter.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/impl/tokenizers/NCEnTokenParser.scala
@@ -14,47 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.nlpcraft.impl.tokenizers
 
-package org.apache.nlpcraft;
+import org.apache.nlpcraft.{NCRequest, NCToken, NCTokenParser}
 
-import java.util.*;
+import java.util;
 
-/**
- *
- */
-public class NCModelConfigAdapter extends NCParameterizedAdapter implements NCModelConfig {
-    @Override
-    public String getId() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getName() {
-        return null; // TODO
-    }
-
-    @Override
-    public String getVersion() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCTokenEnricher> getTokenEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityEnricher> getEntityEnrichers() {
-        return null; // TODO
-    }
-
-    @Override
-    public NCTokenParser getTokenParser() {
-        return null; // TODO
-    }
-
-    @Override
-    public List<NCEntityParser> getEntityParsers() {
-        return null; // TODO
-    }
+class NCEnTokenParser extends NCTokenParser {
+    override def parse(req: NCRequest): util.List[NCToken] = ???
 }
diff --git a/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModel.java b/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModel.java
new file mode 100644
index 0000000..632bc52
--- /dev/null
+++ b/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModel.java
@@ -0,0 +1,73 @@
+/*
+ * 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
+ *
+ *      https://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.alarm;
+
+import org.apache.nlpcraft.NCModelAdapter;
+import org.apache.nlpcraft.*;
+import org.apache.nlpcraft.NCModelConfig;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class LightSwitchModel extends NCModelAdapter {
+    public LightSwitchModel(NCModelConfig cfg) {
+        super(cfg);
+    }
+
+    // TODO: groups ?
+    @NCIntent("intent=ls term(act)={has(tok_groups, 'act')} term(loc)={# == 'ls:loc'}*")
+    @NCIntentSample({
+        "Turn the lights off in the entire house.",
+        "Turn off all lights now",
+        "Switch on the illumination in the master bedroom closet.",
+        "Off the lights on the 1st floor",
+        "Get the lights on.",
+        "Lights up in the kitchen.",
+        "Please, put the light out in the upstairs bedroom.",
+        "Set the lights on in the entire house.",
+        "Turn the lights off in the guest bedroom.",
+        "Could you please switch off all the lights?",
+        "Dial off illumination on the 2nd floor.",
+        "Turn down lights in 1st floor bedroom",
+        "Lights on at second floor kitchen",
+        "Please, no lights!",
+        "Kill off all the lights now!",
+        "Down the lights in the garage",
+        "Lights down in the kitchen!",
+        "Turn up the illumination in garage and master bedroom",
+        "Turn down all the light now!",
+        "No lights in the bedroom, please.",
+        "Light up the garage, please!",
+        "Kill the illumination now!"
+    })
+    NCResult onMatch(
+        @NCIntentTerm("act") NCEntity actTok,
+        @NCIntentTerm("loc") List<NCEntity> locToks) {
+        String status = actTok.getId().equals("ls:on") ? "on" : "off";
+        String locations = locToks.isEmpty() ?
+            "entire house" :
+            locToks.stream().
+                map(p -> p.getTokens().stream().map(x -> x.getOriginalText()).collect(Collectors.joining(" "))).
+                collect(Collectors.joining(", "));
+
+        return new NCResult(
+            "Lights are [" + status + "] in [" + locations.toLowerCase() + "].",
+            NCResultType.ASK_RESULT
+        );
+    }
+}
diff --git a/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModelTest.java b/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModelTest.java
new file mode 100644
index 0000000..92a18ac
--- /dev/null
+++ b/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModelTest.java
@@ -0,0 +1,137 @@
+/*
+ * 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
+ *
+ *      https://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.alarm;
+
+import org.apache.nlpcraft.NCModelClient;
+import org.apache.nlpcraft.NCModelConfigAdapter;
+import org.apache.nlpcraft.NCResult;
+import org.apache.nlpcraft.impl.enrichers.entity.NCFileUserEntityParser;
+import org.apache.nlpcraft.impl.enrichers.entity.NCUserEntityParser;
+import org.apache.nlpcraft.impl.tokenizers.NCEnTokenParser;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.apache.nlpcraft.NCModelConfig;
+import org.apache.nlpcraft.NCEntityParser;
+
+
+import static java.util.Arrays.asList;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class LightSwitchModelTest {
+    @Test
+    public void test() {
+        NCModelClient client = new NCModelClient(new LightSwitchModel(mkConfigManual()));
+
+        Assertions.assertNotNull(client.askSync("Hi!", null, null).getBody());
+    }
+
+    private static NCModelConfigAdapter mkConfigAdapter(NCEntityParser entityParser) {
+        NCModelConfigAdapter cfg =
+            new NCModelConfigAdapter(
+                "nlpcraft.lightswitch.ex",
+                "Light Switch Example Model",
+                "1.0",
+                new NCEnTokenParser()
+            );
+
+        // Order is important.
+//        cfg.setTokenEnrichers(
+//            asList(
+//                new NCEnDictionaryTokenEnricher(),
+//                new NCEnQuotesTokenEnricher(),
+//                new NCEnSwearWordsTokenEnricher()
+//            )
+//        )
+
+        cfg.setEntityParsers(asList(entityParser));
+
+//        // Don't need any entity enrichers.
+//        cfg.setEntityEnrichers(null)
+        return cfg;
+    }
+
+
+    private static NCModelConfigAdapter mkConfigManual() {
+        Map<String, Map<String, String>> elements = new HashMap<>() {{
+            put(
+                "ls:loc",
+                Collections.emptyMap()
+            );
+
+            put("ls:on",
+                new HashMap<>() {{
+                    put("group", "act");
+                }}
+            );
+
+            put("ls:off",
+                new HashMap<>() {{
+                    put("group", "act");
+                }}
+            );
+        }};
+
+        Map<String, String> macros = new HashMap<>() {{
+            put("<ACTION>", "{turn|switch|dial|let|set|get|put}");
+            put("<KILL>", "{shut|kill|stop|eliminate}");
+            put("<ENTIRE_OPT>", "{entire|full|whole|total|_}");
+            put("<FLOOR_OPT>", "{upstairs|downstairs|{1st|first|2nd|second|3rd|third|4th|fourth|5th|fifth|top|ground} floor|_}");
+            put("<TYPE>", "{room|closet|attic|loft|{store|storage} {room|_}}");
+            put("<LIGHT>", "{all|_} {it|them|light|illumination|lamp|lamplight}");
+        }};
+
+        Map<String, List<String>> synonyms = new HashMap<>() {{
+            put(
+                "ls:loc",
+                asList(
+                    "<ENTIRE_OPT> <FLOOR_OPT> {kitchen|library|closet|garage|office|playroom|{dinning|laundry|play} <TYPE>}",
+                    "<ENTIRE_OPT> <FLOOR_OPT> {master|kid|children|child|guest|_} {bedroom|bathroom|washroom|storage} {<TYPE>|_}",
+                    "<ENTIRE_OPT> {house|home|building|{1st|first} floor|{2nd|second} floor}"
+                )
+            );
+
+            put(
+                "ls:on",
+                asList(
+                    "<ACTION> {on|up|_} <LIGHT> {on|up|_}",
+                    "<LIGHT> {on|up}"
+                )
+            );
+
+            put(
+                "ls:off",
+                asList(
+                    "<ACTION> <LIGHT> {off|out|down}",
+                    "{<ACTION>|<KILL>} {off|out|down} <LIGHT>",
+                    "<KILL> <LIGHT>",
+                    "<LIGHT> <KILL>",
+                    "{out|no|off|down} <LIGHT>",
+                    "<LIGHT> {out|off|down}"
+                )
+            );
+
+        }};
+
+        return mkConfigAdapter(new NCUserEntityParser(elements, macros, synonyms));
+    }
+}
diff --git a/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModelTest2.java b/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModelTest2.java
new file mode 100644
index 0000000..47e3ba2
--- /dev/null
+++ b/nlpcraft/src/test/java/org/apache/nlpcraft/alarm/LightSwitchModelTest2.java
@@ -0,0 +1,75 @@
+/*
+ * 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
+ *
+ *      https://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.alarm;
+
+import org.apache.nlpcraft.NCEntityParser;
+import org.apache.nlpcraft.NCModelClient;
+import org.apache.nlpcraft.NCModelConfig;
+import org.apache.nlpcraft.NCModelConfigAdapter;
+import org.apache.nlpcraft.impl.enrichers.entity.NCFileUserEntityParser;
+import org.apache.nlpcraft.impl.enrichers.entity.NCUserEntityParser;
+import org.apache.nlpcraft.impl.tokenizers.NCEnTokenParser;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static java.util.Arrays.asList;
+
+public class LightSwitchModelTest2 {
+    @Test
+    public void test() {
+        NCModelClient client = new NCModelClient(new LightSwitchModel(mkConfigFile(new File("lightswitch.json"))));
+
+        Assertions.assertNotNull(client.askSync("Hi!", null, null).getBody());
+    }
+
+    private static NCModelConfigAdapter mkConfigAdapter(NCEntityParser entityParser) {
+        NCModelConfigAdapter cfg =
+            new NCModelConfigAdapter(
+                "nlpcraft.lightswitch.ex",
+                "Light Switch Example Model",
+                "1.0",
+                new NCEnTokenParser()
+            );
+
+        // Order is important.
+//        cfg.setTokenEnrichers(
+//            asList(
+//                new NCEnDictionaryTokenEnricher(),
+//                new NCEnQuotesTokenEnricher(),
+//                new NCEnSwearWordsTokenEnricher()
+//            )
+//        )
+
+        cfg.setEntityParsers(asList(entityParser));
+
+//        // Don't need any entity enrichers.
+//        cfg.setEntityEnrichers(null)
+        return cfg;
+    }
+
+
+    private static NCModelConfig mkConfigFile(File f) {
+        return mkConfigAdapter(new NCFileUserEntityParser(f));
+    }
+}
diff --git a/nlpcraft/src/test/resources/lightswitch_model.json b/nlpcraft/src/test/resources/lightswitch_model.json
new file mode 100644
index 0000000..f2b7b57
--- /dev/null
+++ b/nlpcraft/src/test/resources/lightswitch_model.json
@@ -0,0 +1,67 @@
+{
+  "elements": [
+    {
+      "ls:loc": [
+      ]
+    },
+    {
+      "ls:on": [
+        {
+          "group": "act"
+        }
+      ]
+    },
+    {
+      "ls:off": [
+        {
+          "group": "act"
+        }
+      ]
+    }
+  ],
+  "macros": [
+    {
+      "<ACTION>": "{turn|switch|dial|let|set|get|put}"
+    },
+    {
+      "<KILL>": "{shut|kill|stop|eliminate}"
+    },
+    {
+      "<ENTIRE_OPT>": "{entire|full|whole|total|_}"
+    },
+    {
+      "<FLOOR_OPT>": "{upstairs|downstairs|{1st|first|2nd|second|3rd|third|4th|fourth|5th|fifth|top|ground} floor|_}"
+    },
+    {
+      "<TYPE>": "{room|closet|attic|loft|{store|storage} {room|_}}"
+    },
+    {
+      "<LIGHT>": "{all|_} {it|them|light|illumination|lamp|lamplight}"
+    }
+  ],
+  "synonyms": [
+    {
+      "ls:loc": [
+        "<ENTIRE_OPT> <FLOOR_OPT> {kitchen|library|closet|garage|office|playroom|{dinning|laundry|play} <TYPE>}",
+        "<ENTIRE_OPT> <FLOOR_OPT> {master|kid|children|child|guest|_} {bedroom|bathroom|washroom|storage} {<TYPE>|_}",
+        "<ENTIRE_OPT> {house|home|building|{1st|first} floor|{2nd|second} floor}"
+      ]
+    },
+    {
+      "ls:on": [
+        "<ACTION> {on|up|_} <LIGHT> {on|up|_}",
+        "<LIGHT> {on|up}"
+      ]
+    },
+    {
+      "ls:off": [
+        "<ACTION> <LIGHT> {off|out|down}",
+        "{<ACTION>|<KILL>} {off|out|down} <LIGHT>",
+        "<KILL> <LIGHT>",
+        "<LIGHT> <KILL>",
+        "{out|no|off|down} <LIGHT>",
+        "<LIGHT> {out|off|down}"
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/nlpcraft/src/test/resources/lightswitch_model.yaml b/nlpcraft/src/test/resources/lightswitch_model.yaml
new file mode 100644
index 0000000..802197c
--- /dev/null
+++ b/nlpcraft/src/test/resources/lightswitch_model.yaml
@@ -0,0 +1,28 @@
+elements:
+  - "ls:loc": []
+  - "ls:on":
+      - "group": "act"
+  - "ls:off":
+      - "group": "act"
+macros:
+  - "<ACTION>": "{turn|switch|dial|let|set|get|put}"
+  - "<KILL>": "{shut|kill|stop|eliminate}"
+  - "<ENTIRE_OPT>": "{entire|full|whole|total|_}"
+  - "<FLOOR_OPT>": "{upstairs|downstairs|{1st|first|2nd|second|3rd|third|4th|fourth|5th|fifth|top|ground} floor|_}"
+  - "<TYPE>": "{room|closet|attic|loft|{store|storage} {room|_}}"
+  - "<LIGHT>": "{all|_} {it|them|light|illumination|lamp|lamplight}"
+synonyms:
+  - "ls:loc":
+      - "<ENTIRE_OPT> <FLOOR_OPT> {kitchen|library|closet|garage|office|playroom|{dinning|laundry|play} <TYPE>}",
+      - "<ENTIRE_OPT> <FLOOR_OPT> {master|kid|children|child|guest|_} {bedroom|bathroom|washroom|storage} {<TYPE>|_}",
+      - "<ENTIRE_OPT> {house|home|building|{1st|first} floor|{2nd|second} floor}"
+  - "ls:on":
+      - "<ACTION> {on|up|_} <LIGHT> {on|up|_}"
+      - "<LIGHT> {on|up}"
+  - "ls:off":
+      - "<ACTION> <LIGHT> {off|out|down}"
+      - "{<ACTION>|<KILL>} {off|out|down} <LIGHT>"
+      - "<KILL> <LIGHT>"
+      - "<LIGHT> <KILL>"
+      - "{out|no|off|down} <LIGHT>"
+      - "<LIGHT> {out|off|down}"