code: public static void addDeepLogger(
          Object object, Consumer<? super String> consumer)
      {
          Objects.requireNonNull(consumer, "The consumer may not be null");
          PropertyChangeListener propertyChangeListener = 
              new PropertyChangeListener()
          {
              @Override
              public void propertyChange(PropertyChangeEvent event)
              {
                  Object source = event.getSource();
                  String propertyName = event.getPropertyName();
                  Object oldValue = event.getOldValue();
                  String oldValueString = createLoggingString(oldValue);
                  Object newValue = event.getNewValue();
                  String newValueString = createLoggingString(newValue);
                  String message = 
                      "Property " + propertyName + " changed from " + 
                      oldValueString + " to " + newValueString + " in " + source;
                  consumer.accept(message);
              }
          };
          addDeepPropertyChangeListener(object, propertyChangeListener);
      }
docs: Attaches a deep property change listener to the given object, that
  generates logging information about the property change events,
  and passes them to the given consumer.
  
  @param object The object
  @param consumer The log message consumer. May not be <code>null</code>.