rulebook-core/src/main/java/com/deliveredtechnologies/rulebook/model/runner/RuleAdapter.java
@SuppressWarnings("unchecked")
  private void mapFactsToProperties(NameValueReferableMap facts) {
    for (Field field : getAnnotatedFields(Given.class, _pojoRule.getClass())) {
      Given given = field.getAnnotation(Given.class);
      try {
        field.setAccessible(true);
        if (NameValueReferable.class.isAssignableFrom(field.getType())) {
          field.set(_pojoRule, facts.get(given.value()));
        } else {
          Object value = facts.getValue(given.value());
          if (value != null) {
            //set the field to the Fact that has the name of the @Given value
            field.set(_pojoRule, value);
          } else if (NameValueReferableMap.class.isAssignableFrom(field.getType())) {
            //if the field is a FactMap then give it the FactMap
            field.set(_pojoRule, facts);
          } else if (Collection.class.isAssignableFrom(field.getType())) {
            //set a Collection of Fact object values
            Stream stream = facts.values().stream()
                    .filter(fact -> { //filter on only facts that contain objects matching the generic type
                      ParameterizedType paramType = (ParameterizedType)field.getGenericType();
                      Class<?> genericType = (Class<?>)paramType.getActualTypeArguments()[0];
                      return genericType.equals(((NameValueReferable) fact).getValue().getClass());
                    })
                    .map(fact -> {
                      ParameterizedType paramType = (ParameterizedType)field.getGenericType();
                      Class<?> genericType = (Class<?>)paramType.getActualTypeArguments()[0];
                      return genericType.cast(((NameValueReferable)fact).getValue());
                    });
            if (List.class == field.getType()) {
              //map List of Fact values to field
              field.set(_pojoRule, stream.collect(Collectors.toList()));
            } else if (Set.class == field.getType()) {
              //map Set of Fact values to field
              field.set(_pojoRule, stream.collect(Collectors.toSet()));
            }
          } else if (Map.class == field.getType()) {
            //map Map of Fact values to field
            Map map = (Map)facts.keySet().stream()
                    .filter(key -> {
                      ParameterizedType paramType = (ParameterizedType)field.getGenericType();
                      Class<?> genericType = (Class<?>)paramType.getActualTypeArguments()[1];
                      return genericType.equals(facts.getValue((String)key).getClass());
                    })
                    .collect(Collectors.toMap(key -> key, key -> facts.getValue((String)key)));
            field.set(_pojoRule, map);
          }
        }
      } catch (Exception ex) {
        LOGGER.error("Unable to update field '" + field.getName() + "' in rule object '"
                + _pojoRule.getClass() + "'", ex);
      }
    }
  }
@SuppressWarnings("unchecked")
  private void mapFactsToProperties(NameValueReferableMap facts) {
    for (Field field : getAnnotatedFields(Given.class, _pojoRule.getClass())) {
      Given given = field.getAnnotation(Given.class);
      try {
        field.setAccessible(true);
        if (NameValueReferable.class.isAssignableFrom(field.getType())) {
          field.set(_pojoRule, facts.get(given.value()));
        } else {
          Object value = facts.getValue(given.value());
          if (value != null) {
            //set the field to the Fact that has the name of the @Given value
            field.set(_pojoRule, value);
          } else if (NameValueReferableMap.class.isAssignableFrom(field.getType())) {
            //if the field is a FactMap then give it the FactMap
            field.set(_pojoRule, facts);
          } else if (Collection.class.isAssignableFrom(field.getType())) {
            //set a Collection of Fact object values
            Stream stream = facts.values().stream()
                    .filter(fact -> { //filter on only facts that contain objects matching the generic type
                      ParameterizedType paramType = (ParameterizedType)field.getGenericType();
                      Class<?> genericType = (Class<?>)paramType.getActualTypeArguments()[0];
                      return genericType.equals(((NameValueReferable) fact).getValue().getClass());
                    })
                    .map(fact -> {
                      ParameterizedType paramType = (ParameterizedType)field.getGenericType();
                      Class<?> genericType = (Class<?>)paramType.getActualTypeArguments()[0];
                      return genericType.cast(((NameValueReferable)fact).getValue());
                    });
            if (List.class == field.getType()) {
              //map List of Fact values to field
              field.set(_pojoRule, stream.collect(Collectors.toList()));
            } else if (Set.class == field.getType()) {
              //map Set of Fact values to field
              field.set(_pojoRule, stream.collect(Collectors.toSet()));
            }
          } else if (Map.class == field.getType()) {
            //map Map of Fact values to field
            Map map = (Map)facts.keySet().stream()
                    .filter(key -> {
                      ParameterizedType paramType = (ParameterizedType)field.getGenericType();
                      Class<?> genericType = (Class<?>)paramType.getActualTypeArguments()[1];
                      return genericType.equals(facts.getValue((String)key).getClass());
                    })
                    .collect(Collectors.toMap(key -> key, key -> facts.getValue((String)key)));
            field.set(_pojoRule, map);
          }
        }
      } catch (Exception ex) {
        LOGGER.error("Unable to update field '" + field.getName() + "' in rule object '"
                + _pojoRule.getClass() + "'", ex);
      }
    }
  }
Convert the Facts to properties with the @Given annotation in the class.
If any matched properties are non-Facts, then the value of the associated Facts are mapped to those
properties. If any matched properties are Facts, then the Fact object are mapped to those properties.