public static function addValue(
    $subject, $property, $value, $options=array()) {
    self::setdefaults($options, array(
      'allowDuplicate' => true,
      'propertyIsArray' => false));

    if(is_array($value)) {
      if(count($value) === 0 && $options['propertyIsArray'] &&
        !property_exists($subject, $property)) {
        $subject->{$property} = array();
      }
      foreach($value as $v) {
        self::addValue($subject, $property, $v, $options);
      }
    } else if(property_exists($subject, $property)) {
      // check if subject already has value if duplicates not allowed
      $has_value = (!$options['allowDuplicate'] &&
        self::hasValue($subject, $property, $value));

      // make property an array if value not present or always an array
      if(!is_array($subject->{$property}) &&
        (!$has_value || $options['propertyIsArray'])) {
        $subject->{$property} = array($subject->{$property});
      }

      // add new value
      if(!$has_value) {
        $subject->{$property}[] = $value;
      }
    } else {
      // add new value as set or single value
      $subject->{$property} = ($options['propertyIsArray'] ?
        array($value) : $value);
    }
  }