code: protected List<? extends ItemData> mergeProps(ItemData rootData, boolean listOnly, DataManager dataManager)
        throws RepositoryException
     {
        // 1 get all transient descendants
        Collection<ItemState> transientDescendants = changesLog.getLastChildrenStates(rootData, false);
  
        if (!transientDescendants.isEmpty())
        {
           // 2 get ALL persisted descendants
           Map<String, ItemData> descendants = new LinkedHashMap<String, ItemData>();
           traverseStoredDescendants(rootData, dataManager, MERGE_PROPS, descendants, listOnly, transientDescendants);
  
           // merge data
           for (ItemState state : transientDescendants)
           {
              ItemData data = state.getData();
              if (!state.isDeleted())
              {
                 descendants.put(data.getIdentifier(), data);
              }
              else
              {
                 descendants.remove(data.getIdentifier());
              }
           }
           Collection<ItemData> desc = descendants.values();
           return new ArrayList<ItemData>(desc);
        }
        else
        {
           return dataManager.getChildPropertiesData((NodeData)rootData);
        }
     }
docs: Merges incoming property data with changes stored in this log i.e: 1. incoming data still not modified
  if there are no corresponding changes 2. incoming data is refreshed with corresponding changes
  if any 3. new datas is added from changes 4. if chaged data is marked as "deleted" it removes
  from outgoing list WARN. THIS METHOD HAS SIBLING - mergeList, see below.
  
  @param rootData
  @param listOnly
  @return