docs: @Override
  	protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder enc)
  	{
  		// Call the initialization of the super type
  		super.initialize(type, oldInstance, newInstance, enc);
  		// Continue only if initializing the "current" type
  		if (type != oldInstance.getClass())
  		{
  			return;
  		}
  
  		// Get all bean properties
  		BeanInfo info = null;
  		try
  		{
  			info = Introspector.getBeanInfo(type);
  		}
  		catch (IntrospectionException ex)
  		{
  			enc.getExceptionListener().exceptionThrown(ex);
  			return;
  		}
  		PropertyDescriptor[] pds = info.getPropertyDescriptors();
  		Method getter, setter;
  		// Initialize each found non-transient property
  		for (int i = 0; i < pds.length; i++)
  		{
  			// Skip a property whose transient attribute is true
  			if (Boolean.TRUE.equals(pds[i].getValue("transient"))) { //$NON-NLS-1$
  				continue;
  			}
  			getter = pds[i].getReadMethod();
  			setter = pds[i].getWriteMethod();
  			// Skip a property having no setter or getter
  			if (getter == null || setter == null)
  			{
  				continue;
  			}
  
  			// Get the value of the property in the old instance
  			Expression getterExp = new Expression(oldInstance, getter.getName(), null);
  			try
  			{
  				// Calculate the old value of the property
  				Object oldVal = getterExp.getValue();
  				// Write the getter expression to the encoder
  				enc.writeExpression(getterExp);
  				// Get the target value that exists in the new environment
  				Object targetVal = enc.get(oldVal);
  				Object newVal = new Expression(newInstance, getter.getName(), null).getValue();
  				if (targetVal == null ? (newVal != null && oldVal == null) : targetVal != newVal && !targetVal.equals(newVal))
  				{
  					enc.writeStatement(new Statement(oldInstance, setter.getName(), new Object[] { oldVal }));
  				}
  			}
  			catch (Exception ex)
  			{
  				enc.getExceptionListener().exceptionThrown(ex);
  			}
  		}
  	}