/**
  * handler for end of element
  *
  * @param	resource	$a_xml_parser		xml parser
  * @param	string		$a_name				element name
  */
 function handlerEndTag($a_xml_parser, $a_name)
 {
     // call meta data handler
     if ($this->in_meta_data && $this->processMeta()) {
         // cache beginning of meta data within media object tags
         // (we need to know the id, after that we send the cached data
         // to the meta xml handler)
         if ($this->in_media_object && $this->media_meta_start) {
             $this->media_meta_cache[] = array("type" => "handlerEndTag", "par1" => $a_name);
         } else {
             parent::handlerEndTag($a_xml_parser, $a_name);
         }
     }
     //echo "<b>END TAG: $a_name <br></b>"; flush();
     // append content to page xml content
     if (($this->in_page_object || $this->in_glossary_definition) && !$this->in_meta_data && !$this->in_media_object) {
         $app_name = $a_name == "Definition" ? "PageObject" : $a_name;
         $this->page_object->appendXMLContent($this->buildTag("end", $app_name));
     }
     // append content to bibitemxml content
     if ($this->in_bib_item) {
         if ($a_name == "BibItem") {
             $this->bib_item->appendXMLContent("\n" . $this->buildTag("end", $a_name));
         } else {
             $this->bib_item->appendXMLContent($this->buildTag("end", $a_name));
         }
     }
     switch ($a_name) {
         case "StructureObject":
             //unset($this->meta_data);
             unset($this->structure_objects[count($this->structure_objects) - 1]);
             break;
         case "PageObject":
             $this->in_page_object = false;
             if ($this->coType != "tst" and $this->coType != "qpl") {
                 if (!$this->lm_page_object->isAlias()) {
                     //$this->page_object->createFromXML();
                     $this->page_object->updateFromXML();
                     $this->pg_mapping[$this->lm_page_object->getImportId()] = $this->lm_page_object->getId();
                     // collect pages with internal links
                     if ($this->page_object->containsIntLink()) {
                         $this->pages_to_parse["lm:" . $this->page_object->getId()] = "lm:" . $this->page_object->getId();
                     }
                     // collect pages with mobs or files
                     if ($this->page_object->needsImportParsing()) {
                         $this->pages_to_parse["lm:" . $this->page_object->getId()] = "lm:" . $this->page_object->getId();
                     }
                     // collect pages with questions
                     if ($this->page_object->getContainsQuestion()) {
                         $this->pages_to_parse["lm:" . $this->page_object->getId()] = "lm:" . $this->page_object->getId();
                     }
                 }
             } else {
                 $xml = $this->page_object->getXMLContent();
                 if ($this->cur_qid != "") {
                     $ids = $this->qst_mapping[$this->cur_qid];
                     if ($ids["pool"] > 0) {
                         // question pool question
                         $page = new ilPageObject("qpl", $ids["pool"]);
                         $xmlcontent = str_replace($this->cur_qid, "il__qst_" . $ids["pool"], $xml);
                         $page->setXMLContent($xmlcontent);
                         $page->saveMobUsage($xmlcontent);
                         $page->updateFromXML();
                         unset($page);
                     }
                     if ($ids["test"] > 0) {
                         // test question
                         $page = new ilPageObject("qpl", $ids["test"]);
                         $xmlcontent = str_replace($this->cur_qid, "il__qst_" . $ids["test"], $xml);
                         $page->setXMLContent($xmlcontent);
                         $page->saveMobUsage($xmlcontent);
                         $page->updateFromXML();
                         unset($page);
                     }
                 }
             }
             // if we are within a structure object: put page in tree
             $cnt = count($this->structure_objects);
             if ($cnt > 0) {
                 $parent_id = $this->structure_objects[$cnt - 1]->getId();
                 if ($this->lm_page_object->isAlias()) {
                     $this->pg_into_tree[$parent_id][] = array("type" => "pg_alias", "id" => $this->lm_page_object->getOriginId());
                 } else {
                     $this->pg_into_tree[$parent_id][] = array("type" => "pg", "id" => $this->lm_page_object->getId());
                 }
             }
             unset($this->page_object);
             unset($this->lm_page_object);
             unset($this->container[count($this->container) - 1]);
             break;
         case "MediaObject":
             $this->in_media_object = false;
             //echo "ENDMediaObject:ImportId:".$this->media_object->getImportId()."<br>";
             // create media object on first occurence of an Id
             if (empty($this->mob_mapping[$this->media_object->getImportId()])) {
                 //echo "No mapping found --creating media object:title:".$this->media_object->getTitle().":<br>";
                 // create media object
                 // media items are saves for mobs outside of
                 // pages only
                 $this->media_object->create(true, false);
                 //echo "<br>creating mob ".$this->media_object->getId().":".$this->media_object->getTitle().":";
                 // collect mobs with internal links
                 if ($this->media_object->containsIntLink()) {
                     //echo "got int link :".$this->media_object->getId().":<br>";
                     $this->mobs_with_int_links[] = $this->media_object->getId();
                 }
                 $this->mob_mapping[$this->media_object->getImportId()] = $this->media_object->getId();
                 //echo "create:import_id:".$this->media_object->getImportId().":ID:".$this->mob_mapping[$this->media_object->getImportId()]."<br>";
             } else {
                 //echo "Mapping found<br>";
                 // get the id from mapping
                 $this->media_object->setId($this->mob_mapping[$this->media_object->getImportId()]);
                 // update "real" (no alias) media object
                 // (note: we overwrite any data from the media object
                 // created by an MediaAlias, only the data of the real
                 // object is stored in db separately; data of the
                 // MediaAliases are within the page XML
                 if (!$this->media_object->isAlias()) {
                     // now the media items are saved within the db
                     $this->media_object->update();
                     //echo "<br>update media object :".$this->media_object->getId().":";
                     // collect mobs with internal links
                     if ($this->media_object->containsIntLink()) {
                         //echo "got int link :".$this->media_object->getId().":<br>";
                         $this->mobs_with_int_links[] = $this->media_object->getId();
                     }
                 }
             }
             // append media alias to page, if we are in a page
             if ($this->in_page_object || $this->in_glossary_definition) {
                 $this->page_object->appendXMLContent($this->media_object->getXML(IL_MODE_ALIAS));
                 //echo "Appending:".htmlentities($this->media_object->getXML(IL_MODE_ALIAS))."<br>";
             }
             break;
         case "MediaItem":
         case "MediaAliasItem":
             $this->in_media_item = false;
             $this->media_object->addMediaItem($this->media_item);
             //echo "adding media item -".$this->media_item->getId()."-".$this->media_item->getLocation()."- to object -".$this->media_object->getId()."-";
             break;
         case "MapArea":
             $this->in_map_area = false;
             $this->media_item->addMapArea($this->map_area);
             break;
         case "Properties":
             $this->in_properties = false;
             if ($this->content_object->getType() == "lm" || $this->content_object->getType() == "dbk") {
                 $this->content_object->update();
             }
             break;
         case "MetaData":
             $this->in_meta_data = false;
             if (strtolower(get_class($this->current_object)) == "illmpageobject" && !$this->in_media_object) {
                 // Metadaten eines PageObjects sichern in NestedSet
                 if (is_object($this->lm_page_object)) {
                     // update title/description of page object
                     $this->current_object->MDUpdateListener('General');
                     ilLMObject::_writeImportId($this->current_object->getId(), $this->current_object->getImportId());
                 }
             } else {
                 if ((strtolower(get_class($this->current_object)) == "ilobjquestionpool" || strtolower(get_class($this->current_object)) == "ilobjtest") && !$this->in_media_object) {
                     if ($this->metadata_parsing_disabled) {
                         $this->enableMDParsing(true);
                     } else {
                         if ($this->in_page_object) {
                             $this->page_object->MDUpdateListener('General');
                             ilLMObject::_writeImportId($this->page_object->getId(), $this->page_object->getImportId());
                         } else {
                             $this->current_object->MDUpdateListener('General');
                             ilLMObject::_writeImportId($this->current_object->getId(), $this->current_object->getImportId());
                         }
                     }
                 } else {
                     if (strtolower(get_class($this->current_object)) == "ilstructureobject") {
                         // save structure object at the end of its meta block
                         // determine parent
                         $cnt = count($this->structure_objects);
                         if ($cnt > 1) {
                             $parent_id = $this->structure_objects[$cnt - 2]->getId();
                         } else {
                             $parent_id = $this->lm_tree->getRootId();
                         }
                         // create structure object and put it in tree
                         //$this->current_object->create(true); // now on top
                         $this->st_into_tree[] = array("id" => $this->current_object->getId(), "parent" => $parent_id);
                         // update title/description of structure object
                         $this->current_object->MDUpdateListener('General');
                         ilLMObject::_writeImportId($this->current_object->getId(), $this->current_object->getImportId());
                     } else {
                         if (strtolower(get_class($this->current_object)) == "ilobjdlbook" || strtolower(get_class($this->current_object)) == "ilobjlearningmodule" || strtolower(get_class($this->current_object)) == "ilobjcontentobject" || strtolower(get_class($this->current_object)) == "ilobjglossary" && $this->in_glossary) {
                             // todo: saving of md? getting title/descr and
                             // set it for current object
                         } else {
                             if (strtolower(get_class($this->current_object)) == "ilglossarydefinition" && !$this->in_media_object) {
                                 // now on top
                                 //$this->glossary_definition->create();
                                 $this->page_object->setId($this->glossary_definition->getId());
                                 $this->page_object->updateFromXML();
                                 // todo: saving of md? getting title/descr and
                                 // set it for current object
                             }
                         }
                     }
                 }
             }
             if (strtolower(get_class($this->current_object)) == "ilobjlearningmodule" || strtolower(get_class($this->current_object)) == "ilobjdlbook" || strtolower(get_class($this->current_object)) == "ilobjglossary") {
                 if (strtolower(get_class($this->current_object)) == "ilobjglossary" && $this->content_object->getType() != "glo") {
                     //echo "<br><b>getting2: ".$this->content_object->getTitle()."</b>";
                     $this->current_object->setTitle($this->content_object->getTitle() . " - " . $this->lng->txt("glossary"));
                 }
                 $this->current_object->MDUpdateListener('General');
                 /*
                 if (!$this->in_media_object && $this->processMeta())
                 {
                 	$this->current_object->update();
                 }
                 */
             }
             if ($this->in_media_object) {
                 //echo "<br>call media object update listener";
                 $this->media_object->MDUpdateListener('General');
             }
             if ($this->in_glossary_definition) {
                 $this->glossary_definition->MDUpdateListener('General');
             }
             break;
         case "Meta-Metadata":
             $this->in_meta_meta_data = false;
             break;
         case "FileItem":
             $this->in_file_item = false;
             // only update new file items
             if ($this->file_item->getImportId($a_attribs["Entry"] != "")) {
                 $this->file_item->update();
             }
             break;
         case "Bibliography":
             $this->in_bib_item = false;
             $nested = new ilNestedSetXML();
             $nested->import($this->bib_item->getXMLContent(), $this->content_object->getId(), "bib");
             break;
         case "Table":
             unset($this->container[count($this->container) - 1]);
             break;
         case "Glossary":
             $this->in_glossary = false;
             break;
         case "GlossaryTerm":
             $this->glossary_term->setTerm(trim($this->chr_data));
             $this->glossary_term->create();
             $iia = explode("_", $this->glossary_term->getImportId());
             $this->glossary_term_map[(int) $iia[count($iia) - 1]] = $this->glossary_term->getId();
             break;
         case "Paragraph":
             $this->inside_code = false;
             break;
         case "Definition":
             $this->in_glossary_definition = false;
             $this->page_object->updateFromXML();
             $this->page_object->buildDom();
             $this->glossary_definition->setShortText($this->page_object->getFirstParagraphText());
             $this->glossary_definition->update();
             //$this->pg_mapping[$this->lm_page_object->getImportId()]
             //	= $this->lm_page_object->getId();
             if ($this->page_object->containsIntLink()) {
                 //echo "<br>Definition contains Int Link:".$this->page_object->getId();
                 $this->pages_to_parse["gdf:" . $this->page_object->getId()] = "gdf:" . $this->page_object->getId();
             }
             if ($this->page_object->needsImportParsing()) {
                 $this->pages_to_parse["gdf:" . $this->page_object->getId()] = "gdf:" . $this->page_object->getId();
             }
             break;
         case "Format":
             if ($this->in_media_item) {
                 $this->media_item->setFormat(trim($this->chr_data));
             }
             if ($this->in_file_item) {
                 $this->file_item->setFileType(trim($this->chr_data));
             }
             break;
         case "Title":
             if (!$this->in_media_object) {
                 $this->current_object->setTitle(trim($this->chr_data));
                 //$this->meta_data->setTitle(trim($this->chr_data));
             } else {
                 $this->media_object->setTitle(trim($this->chr_data));
                 //$this->meta_data->setTitle(trim($this->chr_data));
             }
             break;
         case "Language":
             /*
             				if (is_object($this->meta_data))
             				{
             					$this->meta_data->setLanguage(trim($this->chr_data));
             				}*/
             if (is_object($this->bib_item)) {
                 $this->bib_item->setLanguage(trim($this->chr_data));
             }
             break;
         case "Description":
             //$this->meta_data->setDescription(trim($this->chr_data));
             break;
         case "Caption":
             if ($this->in_media_object) {
                 $this->media_item->setCaption(trim($this->chr_data));
             }
             break;
         case "TextRepresentation":
             if ($this->in_media_object) {
                 $this->media_item->setTextRepresentation(trim($this->chr_data));
             }
             break;
             // Location
         // Location
         case "Location":
             // TODO: adapt for files in "real" subdirectories
             if ($this->in_media_item) {
                 $this->media_item->setLocationType($this->loc_type);
                 if ($this->loc_type == "Reference") {
                     $this->media_item->setLocation(str_replace("&", "&amp;", trim($this->chr_data)));
                 } else {
                     $this->media_item->setLocation(trim($this->chr_data));
                 }
                 //echo "-".$this->media_item->getLocation()."-";
             }
             if ($this->in_file_item) {
                 // set file name from xml file
                 $this->file_item->setFileName(trim($this->chr_data));
                 // special handling for file names with special characters
                 // (e.g. "&gt;")
                 if ($this->file_item->getType() == "file" && is_int(strpos($this->chr_data, "&")) && is_int(strpos($this->chr_data, ";"))) {
                     $imp_dir = $this->content_object->getImportDirectory();
                     $source_dir = $imp_dir . "/" . $this->subdir . "/objects/" . $this->file_item->getImportId();
                     // read "physical" file name from directory
                     if ($dir = opendir($source_dir)) {
                         while (false !== ($file = readdir($dir))) {
                             if ($file != "." && $file != "..") {
                                 $this->file_item->setFileName($file);
                             }
                         }
                         closedir($dir);
                     }
                 }
                 // set file item title
                 $this->file_item->setTitle(trim($this->chr_data));
             }
             break;
     }
     $this->endElement($a_name);
     $this->chr_data = "";
 }