public static function WriteTypedXmlValue(
      \XMLWriter $w, $value, string $name, bool $short = true, bool $separateElements = false)
   {

      if ( ! ( $value instanceof Type ) )
      {
         $value = new Type( $value );
      }

      $v = null;
      $t = null;

      switch ( $value->getType() )
      {

         case Type::PHP_ARRAY:
            $v = \serialize( $value->getValue() );
            $t = Type::PHP_ARRAY;
            break;

         case Type::PHP_BOOLEAN:
            $v = $value->getValue() ? 'true' : 'false';
            $t = Type::PHP_BOOLEAN;
            break;

         case Type::PHP_DOUBLE:
         case Type::PHP_FLOAT:
         case Type::PHP_INTEGER:
            $v = $value->getValue();
            $t = $value->getType();
            break;

         case Type::PHP_NULL:
            $v = '';
            $t = Type::PHP_NULL;
            break;

         case Type::PHP_RESOURCE:
             # Ignore some resources
            break;

         case Type::PHP_STRING:
            $v = $value->getValue();
            $t = Type::PHP_STRING;
            break;

         case Type::PHP_UNKNOWN:
            $v = $value->getStringValue();
            $t = Type::PHP_STRING;
            break;

         default:
            $v = \serialize( $value->getValue() );
            $t = $value->getType();
            break;

      }

      if ( ! \is_null( $t ) && ! \is_null( $v ) )
      {

         $w->startElement( $name );

         if ( $short )
         {
            $w->writeAttribute( 'type', $t );
            $w->writeAttribute( 'value', $v );
         }
         else
         {
            if ( $separateElements )
            {
               $w->writeElement( 'type',  $t );
               $w->writeElement( 'value', $v );
            }
            else
            {
               $w->writeAttribute( 'type', $t );
               $w->text( $v );
            }
         }

         $w->endElement();

      }

   }