protected function saveTranslationImpl(PersistentObject $object, $lang) {
    // if the requested language is the default language, do nothing
    if ($lang == $this->getDefaultLanguage()) {
      // nothing to do
    }
    // save the translations for any other language
    else {
      $object->beforeUpdate();

      // get the existing translations for the requested language
      $query = new ObjectQuery($this->translationType, __CLASS__.'load_save');
      $tpl = $query->getObjectTemplate($this->translationType);
      $tpl->setValue('objectid', Criteria::asValue('=', $object->getOID()->__toString()));
      $tpl->setValue('language', Criteria::asValue('=', $lang));
      $translationInstances = $query->execute(BuildDepth::SINGLE);

      // create map for faster access
      $translations = [];
      foreach ($translationInstances as $translationInstance) {
        $translations[$translationInstance->getValue('attribute')] = $translationInstance;
      }

      // save the translations, ignore pk values
      $pkNames = $object->getMapper()->getPkNames();
      $iter = new NodeValueIterator($object, false);
      for($iter->rewind(); $iter->valid(); $iter->next()) {
        $valueName = $iter->key();
        if (!in_array($valueName, $pkNames)) {
          $curIterNode = $iter->currentNode();
          $translation = isset($translations[$valueName]) ? $translations[$valueName] : null;
          $this->saveTranslatedValue($curIterNode, $valueName, $translation, $lang);
        }
      }
    }
  }