/**
  * Checks whether $actual is okay for $spec.
  *
  * @param PC_Obj_MultiType $actual the actual type
  * @param PC_Obj_MultiType $spec the specified type, i.e., the one to check against
  * @return bool true if ok
  */
 public function is_type_conforming($actual, $spec)
 {
     if ($actual->is_unknown() || $spec->is_unknown()) {
         return true;
     }
     // every actual type has to be contained in at least one of the specified types
     $count = 0;
     foreach ($actual->get_types() as $atype) {
         $ok = false;
         foreach ($spec->get_types() as $stype) {
             if ($atype->equals($stype)) {
                 $ok = true;
                 break;
             }
             // floats can accept ints
             if ($atype->get_type() == PC_Obj_Type::INT && $stype->get_type() == PC_Obj_Type::FLOAT) {
                 $ok = true;
                 break;
             }
             // if both are objects, check if the actual is the same or a subclass of the spec
             $objs = $atype->get_type() == PC_Obj_Type::OBJECT && $stype->get_type() == PC_Obj_Type::OBJECT;
             if ($objs && ($stype->get_class() == '' || (strcasecmp($atype->get_class(), $stype->get_class()) || $this->is_subclass_of($atype->get_class(), $stype->get_class())))) {
                 $ok = true;
                 break;
             }
         }
         // early exit?
         if (!$ok && $this->options->get_report_argret_strictly()) {
             return false;
         }
         if ($ok && !$this->options->get_report_argret_strictly()) {
             return true;
         }
         if ($ok) {
             $count++;
         }
     }
     return $count > 0;
 }