/**
  * Attach a component to this component (alarm inside event for example)
  * @param qCal_Component $component The component to be attached to this component
  * @access public
  * @return $this
  * @todo There may be an issue with the way this is done. When parsing a file, if a component
  * or property with a tzid comes before its corresponding vtimezone component, an exception
  * will be thrown. I'm don't think the RFC specifies that requirement (that timezone components
  * must come before their corresponding tzids)
  * @todo Sub-components such as Vevent need to be able to access the main vcalendar object
  * for several reasons. 
  * 		 - If a vtodo has a tzid, it needs to be able to determine that the corresponding 
  * 		   vtimezone component is available.
  * 		 - If components need to relate to eachother, they can only find eachother through
  * 		   the main vcalendar object.
  * 		 - Freebusy time can only be determined by polling all components in the main vcalendar
  * 		   object.
  * 		 - More to come probably
  */
 public function attach(qCal_Component $component)
 {
     if (!$component->canAttachTo($this)) {
         throw new qCal_Exception_InvalidComponent($component->getName() . ' cannot be attached to ' . $this->getName());
     }
     $component->setParent($this);
     // make sure if a timezone is requested that it is available...
     $timezones = $this->getTimezones();
     // we only need to check if tzid exists if we are attaching something other than a timezone...
     if (!$component instanceof qCal_Component_Vtimezone) {
         foreach ($component->getProperties() as $pname => $properties) {
             $pname = strtoupper($pname);
             // probably redundant...
             foreach ($properties as $property) {
                 switch ($pname) {
                     case "TZID":
                         $tzid = strtoupper($property->getValue());
                         if (!array_key_exists($tzid, $timezones)) {
                             throw new qCal_Exception_MissingComponent('TZID "' . $tzid . '" not defined');
                         }
                         break;
                 }
                 $params = $property->getParams();
                 foreach ($params as $param => $val) {
                     $param = strtoupper($param);
                     // probably redundant...
                     switch ($param) {
                         case "TZID":
                             $tzid = strtoupper($val);
                             if (!array_key_exists($tzid, $timezones)) {
                                 throw new qCal_Exception_MissingComponent('TZID "' . $tzid . '" not defined');
                             }
                             break;
                     }
                 }
             }
         }
     }
     $this->children[$component->getName()][] = $component;
     return $this;
 }