code: static void updateProperties(Element e, Map<String, Object> properties, String[] disallowedProperties) {
          if (properties == null) {
              return;
          }
  
          Set<String> disallowed = new HashSet<>(Arrays.asList(disallowedProperties));
  
          //remove all non-mapped properties, that are not in the update
          Spliterator<Property<?>> sp = Spliterators.spliteratorUnknownSize(e.properties(),
                  Spliterator.NONNULL & Spliterator.IMMUTABLE);
          Property<?>[] toRemove = StreamSupport.stream(sp, false)
                  .filter((p) -> !disallowed.contains(p.key()) && !properties.containsKey(p.key()))
                  .toArray(Property[]::new);
  
          for (Property<?> p : toRemove) {
              p.remove();
          }
  
          //update and add new the properties
          properties.forEach((p, v) -> {
              if (!disallowed.contains(p)) {
                  e.property(p, v);
              }
          });
      }
docs: Updates the properties of the element, disregarding any changes of the disallowed properties
  
  <p> The list of the disallowed properties will usually come from
  {@link Constants.Type#getMappedProperties()}.
  
  @param e                    the element to update properties of
  @param properties           the properties to update
  @param disallowedProperties the list of properties that are not allowed to change.