package org.springframework.binding.value.support;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;
import java.beans.VetoableChangeSupport;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.binding.value.PropertyChangePublisher;
import org.springframework.binding.value.ValueChangeDetector;
import org.springframework.richclient.application.Application;

public abstract class AbstractPropertyChangePublisher implements
        PropertyChangePublisher {

    protected final Log logger = LogFactory.getLog(getClass());

    private transient PropertyChangeSupport changeSupport;

    private transient VetoableChangeSupport vetoSupport;

    private ValueChangeDetector valueChangeDetector;

    public final void addPropertyChangeListener(PropertyChangeListener listener) {
        if (listener == null) { return; }
        if (changeSupport == null) {
            changeSupport = new PropertyChangeSupport(this);
        }
        changeSupport.addPropertyChangeListener(listener);
    }

    public final void removePropertyChangeListener(
            PropertyChangeListener listener) {
        if (listener == null || changeSupport == null) { return; }
        changeSupport.removePropertyChangeListener(listener);
    }

    public final void addPropertyChangeListener(String propertyName,
            PropertyChangeListener listener) {
        if (listener == null) { return; }
        if (changeSupport == null) {
            changeSupport = new PropertyChangeSupport(this);
        }
        changeSupport.addPropertyChangeListener(propertyName, listener);
    }

    public final void removePropertyChangeListener(String propertyName,
            PropertyChangeListener listener) {
        if (listener == null || changeSupport == null) { return; }
        changeSupport.removePropertyChangeListener(propertyName, listener);
    }

    public final void addVetoableChangeListener(
            VetoableChangeListener listener) {
        if (listener == null) { return; }
        if (vetoSupport == null) {
            vetoSupport = new VetoableChangeSupport(this);
        }
        vetoSupport.addVetoableChangeListener(listener);
    }

    public final void removeVetoableChangeListener(
            VetoableChangeListener listener) {
        if (listener == null || vetoSupport == null) { return; }
        vetoSupport.removeVetoableChangeListener(listener);
    }

    public final void addVetoableChangeListener(String propertyName,
            VetoableChangeListener listener) {
        if (listener == null) { return; }
        if (vetoSupport == null) {
            vetoSupport = new VetoableChangeSupport(this);
        }
        vetoSupport.addVetoableChangeListener(propertyName, listener);
    }

    public final void removeVetoableChangeListener(String propertyName,
            VetoableChangeListener listener) {
        if (listener == null || vetoSupport == null) { return; }
        vetoSupport.removeVetoableChangeListener(propertyName, listener);
    }

    public final PropertyChangeListener[] getPropertyChangeListeners() {
        if (changeSupport == null) { return new PropertyChangeListener[0]; }
        return changeSupport.getPropertyChangeListeners();
    }

    public final PropertyChangeListener[] getPropertyChangeListeners(
            String propertyName) {
        if (changeSupport == null) { return new PropertyChangeListener[0]; }
        return changeSupport.getPropertyChangeListeners(propertyName);
    }

    public final VetoableChangeListener[] getVetoableChangeListeners() {
        if (vetoSupport == null) { return new VetoableChangeListener[0]; }
        return vetoSupport.getVetoableChangeListeners();
    }

    public final VetoableChangeListener[] getVetoableChangeListeners(
            String propertyName) {
        if (vetoSupport == null) { return new VetoableChangeListener[0]; }
        return vetoSupport.getVetoableChangeListeners(propertyName);
    }

    protected final void firePropertyChange(String propertyName,
            Object oldValue, Object newValue) {
        PropertyChangeSupport aChangeSupport = this.changeSupport;
        if (aChangeSupport == null) { return; }
        aChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
    }

    protected final void firePropertyChange(String propertyName,
            boolean oldValue, boolean newValue) {
        PropertyChangeSupport aChangeSupport = this.changeSupport;
        if (aChangeSupport == null) { return; }
        aChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
    }

    protected final void firePropertyChange(String propertyName,
            double oldValue, double newValue) {
        firePropertyChange(propertyName, new Double(oldValue), new Double(
                newValue));
    }

    protected final void firePropertyChange(String propertyName,
            float oldValue, float newValue) {
        firePropertyChange(propertyName, new Float(oldValue), new Float(
                newValue));
    }

    protected final void firePropertyChange(String propertyName, int oldValue,
            int newValue) {
        PropertyChangeSupport aChangeSupport = this.changeSupport;
        if (aChangeSupport == null) { return; }
        aChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
    }

    protected final void firePropertyChange(String propertyName, long oldValue,
            long newValue) {
        firePropertyChange(propertyName, new Long(oldValue), new Long(newValue));
    }

    protected final void firePropertiesChanged() {
        firePropertyChange(null, null, null);
    }

    protected final void fireVetoableChange(String propertyName,
            Object oldValue, Object newValue) throws PropertyVetoException {
        VetoableChangeSupport aVetoSupport = this.vetoSupport;
        if (aVetoSupport == null) { return; }
        aVetoSupport.fireVetoableChange(propertyName, oldValue, newValue);
    }

    protected final void fireVetoableChange(String propertyName,
            boolean oldValue, boolean newValue) throws PropertyVetoException {
        VetoableChangeSupport aVetoSupport = this.vetoSupport;
        if (aVetoSupport == null) { return; }
        aVetoSupport.fireVetoableChange(propertyName, oldValue, newValue);
    }

    protected final void fireVetoableChange(String propertyName,
            double oldValue, double newValue) throws PropertyVetoException {
        fireVetoableChange(propertyName, new Double(oldValue), new Double(
                newValue));
    }

    protected final void fireVetoableChange(String propertyName, int oldValue,
            int newValue) throws PropertyVetoException {
        VetoableChangeSupport aVetoSupport = this.vetoSupport;
        if (aVetoSupport == null) { return; }
        aVetoSupport.fireVetoableChange(propertyName, oldValue, newValue);
    }

    protected final void fireVetoableChange(String propertyName,
            float oldValue, float newValue) throws PropertyVetoException {
        fireVetoableChange(propertyName, new Float(oldValue), new Float(
                newValue));
    }

    protected final void fireVetoableChange(String propertyName, long oldValue,
            long newValue) throws PropertyVetoException {
        fireVetoableChange(propertyName, new Long(oldValue), new Long(newValue));
    }

    protected boolean hasChanged(Object currentValue, Object proposedValue) {
        return getValueChangeDetector().hasValueChanged(currentValue, proposedValue);
    }

    protected final boolean hasChanged(boolean currentValue, boolean proposedValue) {
        return currentValue != proposedValue;
    }

    protected final boolean hasChanged(int currentValue, int proposedValue) {
        return currentValue != proposedValue;
    }

    protected final boolean hasChanged(long currentValue, long proposedValue) {
        return currentValue != proposedValue;
    }

    protected final boolean hasChanged(float currentValue, float proposedValue) {
        return currentValue != proposedValue;
    }

    protected final boolean hasChanged(double currentValue, double proposedValue) {
        return currentValue != proposedValue;
    }

    /**
     * Set the object that will be used to detect changes between two objects.
     * @param valueChangeDetector to use
     */
    public void setValueChangeDetector(ValueChangeDetector valueChangeDetector) {
        this.valueChangeDetector = valueChangeDetector;
    }

    /**
     * Get the value change detector to use for object comparisons.
     * @return detector to use
     */
    protected ValueChangeDetector getValueChangeDetector() {
        if( valueChangeDetector == null ) {
            valueChangeDetector = Application.services().getValueChangeDetector();
        }
        return valueChangeDetector;
    }
}
@@ -435,104 +435,24 @@
 ork.
-binding.value.ValueChangeDetector;%0Aimport org.springframework.richclient.application.Application
+util.ObjectUtils
 ;%0A%0Ap
@@ -737,62 +737,8 @@
 t;%0A%0A
-    private ValueChangeDetector valueChangeDetector;%0A%0A
     
@@ -7463,48 +7463,35 @@
 urn 
-getValueChangeDetector().hasValueChanged
+!ObjectUtils.nullSafeEquals
 (cur
@@ -8203,641 +8203,5 @@
  %7D%0A%0A
-    /**%0A     * Set the object that will be used to detect changes between two objects.%0A     * @param valueChangeDetector to use%0A     */%0A    public void setValueChangeDetector(ValueChangeDetector valueChangeDetector) %7B%0A        this.valueChangeDetector = valueChangeDetector;%0A    %7D%0A%0A    /**%0A     * Get the value change detector to use for object comparisons.%0A     * @return detector to use%0A     */%0A    protected ValueChangeDetector getValueChangeDetector() %7B%0A        if( valueChangeDetector == null ) %7B%0A            valueChangeDetector = Application.services().getValueChangeDetector();%0A        %7D%0A        return valueChangeDetector;%0A    %7D%0A
 %7D

Remove VCD handling and revert to prior hasChanged implementation