private function restrictByValueType(PhpType $type = null, $outcome, $typeName)
 {
     // If the type function evaluates to true, we can always say what
     // the type is afterwards even if we do not know the input.
     if ($outcome) {
         return $this->typeRegistry->getNativeType($typeName);
     }
     if (null === $type) {
         return null;
     }
     // If we know the outcome is false, and only the given type is passed,
     // e.g. is_array() receives only arrays, then this condition always
     // evaluates to false.
     if ($type->{'is' . $typeName . 'Type'}()) {
         return $this->typeRegistry->getNativeType('none');
     }
     // If a union type is passed, the value can be whatever the union type
     // represents minus the checked type.
     if ($type->isUnionType()) {
         return $type->getRestrictedUnion($this->typeRegistry->getNativeType($typeName));
     }
     // If an all type is passed, the value can be all value types minus the
     // checked value type.
     if ($type->isAllType()) {
         $allTypes = array('object', 'integer', 'double', 'string', 'null', 'array', 'boolean');
         unset($allTypes[array_search($typeName, $allTypes, true)]);
         return $this->typeRegistry->createUnionType($allTypes);
     }
     // If nothing from above is applicable, just return the type. It is an
     // indication that the condition is always false, for example
     // is_array() receives always non-array values.
     return $type;
 }