code: public static ObservedObject addDeepPropertyChangeListener(
          Object object, PropertyChangeListener propertyChangeListener)
      {
          Objects.requireNonNull(object, "The object may not be null");
          Objects.requireNonNull(propertyChangeListener, 
              "The propertyChangeListener may not be null");
          
          PropertyChangeListener forwardingPropertyChangeListener = 
              new PropertyChangeListener()
          {
              @Override
              public void propertyChange(PropertyChangeEvent event)
              {
                  Object oldValue = event.getOldValue();
                  Object newValue = event.getNewValue();
                  removeRecursive(oldValue, propertyChangeListener);
                  removeRecursive(oldValue, this);
                  addRecursive(newValue, propertyChangeListener);
                  addRecursive(newValue, this);
              }
          };
          
          addRecursive(object, propertyChangeListener);
          addRecursive(object, forwardingPropertyChangeListener);
          
          ObservedObject observedObject = new ObservedObject(object, 
              propertyChangeListener, forwardingPropertyChangeListener);
          return observedObject;
      }
docs: Add the given property change listener to the given object and all
  its sub-objects, and make sure that the property change listener
  will be attached to all sub-objects that are set, and removed from
  all sub-objects that are removed.<br>
  <br>
  The returned {@link ObservedObject} instance may be used to
  detach all property change listeners that have been attached
  with this call:
  <pre><code>
  ObservedObject observedObject =
  PropertyChangeListeners.addDeepPropertyChangeListener(someObject, p);
  
  // Set some properties, informing the PropertyChangeListeners
  someObject.setFoo("foo");
  someObject.getInnerObject().setBar("bar");
  
  // Detach the deep property change listener:
  observedObject.detach();
  </code></pre>
  
  @param object The object
  @param propertyChangeListener The property change listener
  @return The {@link ObservedObject}