code: def test_custom_multi_feature_factory(self):
      # Given
  
      # pylint:disable=unused-variable
      @CRFFeatureFactory.register(
          "my_multi_feature_factory", override=True
      )
      class MyMultiFeature(CRFFeatureFactory):
          def build_features(self):
              first_features = [
                  Feature(
                      "my_first_feature",
                      self.compute_feature_1,
                      offset=offset,
                  )
                  for offset in self.offsets
              ]
              second_features = [
                  Feature(
                      "my_second_feature",
                      self.compute_feature_2,
                      offset=offset,
                  )
                  for offset in self.offsets
              ]
              return first_features + second_features
  
          @staticmethod
          def compute_feature_1(tokens, token_index):
              return "(%s)[my_feature_1]" % tokens[token_index].value
  
          @staticmethod
          def compute_feature_2(tokens, token_index):
              return "(%s)[my_feature_2]" % tokens[token_index].value
  
      # pylint:enable=unused-variable
  
      # When
      config = {
          "factory_name": "my_multi_feature_factory",
          "args": {},
          "offsets": [-1, 0],
      }
      feature_factory = CRFFeatureFactory.from_config(config)
      features = feature_factory.build_features()
      feature_0 = features[0]
      feature_1 = features[1]
      feature_2 = features[2]
      feature_3 = features[3]
      tokens = tokenize("foo bar baz", "en")
      cache = [{TOKEN_NAME: token} for token in tokens]
  
      # Then
      self.assertEqual("my_first_feature[-1]", feature_0.name)
      self.assertEqual(
          "(foo)[my_feature_1]", feature_0.compute(1, cache)
      )
      self.assertEqual("my_first_feature", feature_1.name)
      self.assertEqual("my_second_feature[-1]", feature_2.name)
      self.assertEqual(
          "(bar)[my_feature_2]", feature_2.compute(2, cache)
      )
      self.assertEqual("my_second_feature", feature_3.name)
  
imports: from __future__ import unicode_literals
  import io
  from mock import MagicMock
  from snips_nlu.constants import LANGUAGE, LANGUAGE_EN, SNIPS_DATETIME, SNIPS_NUMBER, STEMS, GAZETTEERS, WORD_CLUSTERS
  from snips_nlu.dataset import Dataset
  from snips_nlu.entity_parser import BuiltinEntityParser, CustomEntityParser
  from snips_nlu.entity_parser.custom_entity_parser_usage import CustomEntityParserUsage
  from snips_nlu.exceptions import NotRegisteredError
  from snips_nlu.preprocessing import tokenize
  from snips_nlu.slot_filler.crf_utils import BEGINNING_PREFIX, INSIDE_PREFIX, LAST_PREFIX, TaggingScheme, UNIT_PREFIX
  from snips_nlu.slot_filler.feature import Feature, TOKEN_NAME
  from snips_nlu.slot_filler.feature_factory import BuiltinEntityMatchFactory, CustomEntityMatchFactory, IsDigitFactory, IsFirstFactory, IsLastFactory, LengthFactory, NgramFactory, PrefixFactory, ShapeNgramFactory, SingleFeatureFactory, SuffixFactory, WordClusterFactory, CRFFeatureFactory
  from snips_nlu.tests.utils import SnipsTest
label_desc: Use image node_id 20 for calling the TestCRFFeatures obj's underlying member method code with example usage: obj.test_custom_multi_feature_factory() and returns: unknown, unknown, unknown