private function _commit(Wrapper_FS_Changes $changes, $path = "")
  {
    $root = $this->getRoot();
    $rootpath = $root->path();

    if ($path) {
      $path .= "/";
    }

    $own = $changes->own();
    foreach ($own as $filename => $vEntity) {
      $filepath = $path . $filename;
      $rPath = $rootpath . "/" . $filepath;

      /* @var $vEntity Entity_Abstract|Entity_Virtual_Interface */
      $vExists = $vEntity->file_exists();
      $rDeleted = false;

      $rEntity = $vEntity;
      do {
        $rEntity = $rEntity->getRealEntity();
        $rDeleted = $rDeleted || !$rEntity->file_exists();
      } while ($rEntity instanceof Entity_Virtual_Interface);
      /* @var $rEntity Entity */
      $rExists = $rEntity->file_exists();
      if ($rExists && !$vExists) {
        $rDeleted = true;
      }

      if (!$vExists && !$rExists) {
        continue;
      } elseif ($rDeleted) {
        if ($rExists) {
          $this->_files->delete($rPath);
        }
        if ($vExists) {
          $this->_copyChanges($filepath);
        }
      } else {
        /* @var $vEntity Entity_Virtual */
        if ($vEntity->is_file()) {
          unlink($rPath);
          copy($vEntity->path(), $rPath);
        }
      }
    }

    $subtrees = $changes->sublists();
    foreach ($subtrees as $filename => $tree) {
      /* @var $tree Wrapper_FS_Changes */
      if (!isset($own[$filename])) {
        $this->_commit($tree, $path . $filename);
      }
    }

  }