code: public void addChange(String valuePath, String attributeName, int valueIndex, ChangeType changeType) {
  
          if (ChangeType.value.equals(changeType)) {
              if (m_changeTimer != null) {
                  if (!m_changeTimer.matches(valuePath, attributeName, valueIndex)) {
                      // only in case the change properties of the timer do not match the current change,
                      // add the last change and start a new timer
                      m_changeTimer.cancel();
                      m_changeTimer.run();
                      m_changeTimer = new ChangeTimer(valuePath, attributeName, valueIndex, changeType);
                      m_changeTimer.schedule(CHANGE_TIMER_DELAY);
                  }
              } else {
                  m_changeTimer = new ChangeTimer(valuePath, attributeName, valueIndex, changeType);
                  m_changeTimer.schedule(CHANGE_TIMER_DELAY);
              }
          } else {
              if (m_changeTimer != null) {
                  m_changeTimer.cancel();
                  m_changeTimer.run();
              }
              internalAddChange(valuePath, attributeName, valueIndex, changeType);
          }
      }
docs: Adds a change to the undo stack.<p>
  
  @param valuePath the entity value path
  @param attributeName the attribute name
  @param valueIndex the value index
  @param changeType the change type