Get the xequal comparison type an attribute
@param XBRL_Types $types
@param string $localName
@param string|null $prefix
@return number
198222
public static function xequalAttributeType( $types, $localName, $prefix )
	{
		$attribute = $types->getAttribute( $localName, $prefix );
		if ( ! $attribute || ! isset( $attribute['types'] ) || ! count( $attribute['types'] ) ) return XBRL_Equality::$EQUALITY_TYPE_STRING;

		return XBRL_Equality::xEqualComparisonType( array( 'type' => $attribute['types'][0] ), $types);
	}
1220158
private function handleTypes( $node, $prefix )
	{
		switch ( $node->getName() )
		{
			case 'simpleType':

				return $this->getSimpleType( $node, $prefix );

				break;

			case 'complexType':

				return $this->getComplexType( $node, $prefix );

				break;

		}

		return false;
	}
522707
public static function isEqualType(TypeInterface $typeA, TypeInterface $typeB): bool
    {
        // Equivalent types are equal.
        if ($typeA === $typeB) {
            return true;
        }

        // If either type is non-null, the other must also be non-null.
        if ($typeA instanceof NonNullType && $typeB instanceof NonNullType) {
            return self::isEqualType($typeA->getOfType(), $typeB->getOfType());
        }

        // If either type is a list, the other must also be a list.
        if ($typeA instanceof ListType && $typeB instanceof ListType) {
            return self::isEqualType($typeA->getOfType(), $typeB->getOfType());
        }

        // Otherwise the types are not equal.
        return false;
    }
1047223
public function AddSimpleType( $prefix, $localName, $parentType = "xs:anySimpleType", $numeric = false )
	{
		$name = "$prefix:$localName";

		if ( isset( $this->types[ $name ] ) ) return false;

		$parentType = is_null( $parentType ) ? "xs:anySimpleType" : $parentType;

		$this->types[ $name ] = array(
			"parent" => $parentType,
			"prefix" => $prefix,
			"name" => $localName,
			"numeric" => false,
		);

		// BMS 2018-04-09 Fixing the kluge
		if ( $prefix == SCHEMA_PREFIX && ! isset( SchemaTypes::$xsTypes[ $name ] ) )
		{
			SchemaTypes::$xsTypes[ $name ] = $parentType;
		}
	}
229353
public function blockCompare($GlobalBlock, $LocalBlock, $Len)
    {
        for ($i = 0; $i < $Len; $i++) {
            if (
                $GlobalBlock{3 * $i + 0} != $LocalBlock{3 * $i + 0} ||
                $GlobalBlock{3 * $i + 1} != $LocalBlock{3 * $i + 1} ||
                $GlobalBlock{3 * $i + 2} != $LocalBlock{3 * $i + 2}
            ) {
                return (0);
            }
        }
        return (1);
    }
1078115
private function getType($alias) {
        if (isset(self::$types[$alias])) {
            return $alias;
        }
        foreach (self::$types as $type => $aliases) {
            if (in_array($alias, $aliases, true)) {
                return $type;
            }
        }
        return null;
    }
830750
public static function isStandardArcElement( $namespaceURI, $localName )
	{
		return	$namespaceURI == self::$standardPrefixes[ STANDARD_PREFIX_LINK ]  &&
				isset( self::$standardArcElements[ $localName ] ) ||
				qnameNsLocalName( $namespaceURI, $localName )->equals( self::qnameNS( self::$ixRelationship ) );
	}
87662
public function lookup(string $localType): string
    {
        $localType = \trim($localType);
        
        if ($localType === '') {
            return $this->namespace;
        }
        
        if ($localType[0] === '\\') {
            return \trim($localType, '\\');
        }
        
        $type = \strtolower($localType);
        
        if (\strpos($type, '\\') === false) {
            // Type import lookup.
            if (\array_key_exists($type, $this->imports)) {
                return $this->imports[$type];
            }
        } else {
            // Namespace import lookup.
            $tmp = \explode('\\', $localType, 2);
            $tmp[0] = \strtolower($tmp[0]);
            
            if (\array_key_exists($tmp[0], $this->imports)) {
                return \ltrim($this->imports[$tmp[0]] . '\\' . $tmp[1], '\\');
            }
        }
        
        return \ltrim($this->namespace . '\\', '\\') . $localType;
    }
705222
private function validateEssenceAliasArcs( XBRL_Types &$types )
	{

		$arcs = $this->getInstanceTaxonomy()->getEssenceAliasList();
		if ( ! $arcs ) return true;

		/* ---------------------------------------------------------
		 * Look for directed cycles
		 * ---------------------------------------------------------
		 */

		/**
		 * Examine the arcs recursively to look for directed cycles.
		 * If there are directed cyles then the $alias of an arc will appear in the list of $parents
		 *
		 * @var function $detectDirected
		 * @param string $essence
		 * @param array $parents
		 * @return bool
		 */
		$detectDirected = function( $essence, $parents = array() ) use( &$detectDirected, &$arcs )
		{
			foreach ( $arcs[ $essence ] as $alias => $details )
			{
				if ( $alias == $essence || in_array( $alias, $parents ) ) return true;

				if ( ! isset( $arcs[ $alias ] ) ) continue;

				if ( $detectDirected( $alias, array_merge( $parents, array( $essence ) ) ) )
				{
					XBRL_Log::getInstance()->instance_validation( "5.2.6.2.2", "The essence alias arcs contain directed cycles",
						array(
							'path' => implode( '->', $parents ),
						)
					);

					return true;
				}
			}

			return false;
		};

		foreach ( $arcs as $essence => $aliases )
		{
			if ( $detectDirected( $essence ) )
			{
				return false;
			}
		}

		/* ---------------------------------------------------------
		 * Check each arc
		 * ---------------------------------------------------------
		 */

		foreach ( $arcs as $essence => $aliases )
		{
			// echo "$essence\n";

			$parts = parse_url( $essence );
			if ( ! isset( $parts['path'] ) || ! isset( $parts['fragment'] ) ) continue;

			$essenceTaxonomy = $this->getInstanceTaxonomy()->getTaxonomyForXSD( $parts['path'] );
			if ( ! $essenceTaxonomy )
			{
				$this->log()->instance_validation( "5.2.6.2.2", "The taxonomy of the source does not exist in the DTS",
					array(
						'from' => $essence,
					)
				);
				continue;
			}

			$essenceElement = $essenceTaxonomy->getElementById( $parts['fragment'] );
			if ( ! $essenceElement )
			{
				$this->log()->instance_validation( "5.2.6.2.2", "The concept of the source does not exist in the DTS",
					array(
						'essence' => $essence,
					)
				);
				continue;
			}

			$type = $types->getType( $essenceElement['type'] );
			if ( ! $type )
			{
				$this->log()->instance_validation( "5.2.6.2.2" , "Cannot locate type information for the essence",
					array(
						'type' => $essenceElement['type'],
						'element' => $essence,
					)
				);
				continue;
			}

			// Look for the essence fact(s) in the instance document
			$essenceFact = $this->getElement( $essenceElement['id'] );

			// If the $from does not exist then infer the value
			$essenceAliasValues = array(); // Holds a list of inferred values grouped by parent nodes
			$combinations = new TupleDictionary();

			foreach ( $aliases as $alias => $details )
			{
				// echo "\t-> $alias\n";

				$parts = parse_url( $alias );
				if ( ! isset( $parts['path'] ) || ! isset( $parts['fragment'] ) ) continue;

				$aliasTaxonomy = $this->getInstanceTaxonomy()->getTaxonomyForXSD( $parts['path'] );
				if ( ! $aliasTaxonomy )
				{
					$this->log()->instance_validation( "5.2.6.2.2", "The taxonomy of the alias does not exist in the DTS",
						array(
							'alias' => $alias,
						)
					);
					continue;
				}

				$aliasElement = $aliasTaxonomy->getElementById( $parts['fragment'] );
				if ( ! $aliasElement )
				{
					$this->log()->instance_validation( "5.2.6.2.2", "The concept of the alias does not exist in the DTS",
						array(
							'alias' => $alias,
						)
					);
					continue;
				}

				// The element definitions should always have an type but its worth checking
				if ( XBRL_Instance::isEmpty( $aliasElement, 'type' ) || XBRL_Instance::isEmpty( $essenceElement, 'type' ) )
				{
					$this->log()->taxonomy_validation( "5.1.1.1", "Missing type attribute on essence or alias",
						array(
							'essence' => $essence,
							'alias' => $alias,
							'point' => '3',
							'essence_type' => $essenceElement['type'],
							'alias_type' => $aliasElement['type'],
						)
					);
					continue;
				}

				// The type of the essence and the alias must be the same
				if ( $aliasElement['type'] != $essenceElement['type'] )
				{
					continue;
				}

				// The element definitions should always have a periodType but its worth checking
				if ( XBRL_Instance::isEmpty( $aliasElement, 'periodType' ) || XBRL_Instance::isEmpty( $essenceElement, 'periodType' ) )
				{
					$this->log()->taxonomy_validation( "5.1.1.1", "Missing periodType attribute on essence or alias",
						array(
							'essence' => $essence,
							'alias' => $alias,
							'point' => '3',
							'essence_period_type' => $essenceElement['periodType'],
							'alias_period_type' => $aliasElement['periodType'],
						)
					);
					continue;
				}

				// The period type of both concepts MUST be the same
				if ( $aliasElement['periodType'] != $essenceElement['periodType'] )
				{
					$this->log()->instance_validation( "5.2.6.2.2", "The period types of the essence and alias are not compatible",
						array(
							'essence' => $essence,
							'alias' => $alias,
							'point' => '3',
							'essence_period_type' => $essenceElement['periodType'],
							'alias_period_type' => $aliasElement['periodType'],
						)
					);
					continue;
				}

				// If the alias and essence concepts include balance attribute then the value MUST be the same
				if ( ! XBRL_Instance::isEmpty( $aliasElement, 'balance' ) && ! XBRL_Instance::isEmpty( $essenceElement, 'balance' ) )
				{
					if (  $aliasElement['balance'] != $essenceElement['balance'] )
					{
						continue;
					}
				}

				// Look for the fact in the instance document
				$aliasFact = $this->getElement( $aliasElement['id'] );

				// If the $from does not exist there is noting else to do
				if ( ! $aliasFact ) continue;

				// Getting here means there is an essence concept and an alias concept that are equal
				// Now take a look at the facts

				if ( ! $essenceFact )
				{
					// If there is no essence fact infer any values
					foreach ( $aliasFact as $aliasEntryKey => $aliasEntry )
					{
						$value = $type['numeric']
							? $this->getNumericPresentation( $aliasEntry )
							: $aliasEntry['value'];

						// Create a key
						$key = array(
							'name' => $aliasElement['id'],
							'parent' => $aliasEntry['parent'],
							'context' => $this->getContext( $aliasEntry['contextRef'] ),
							'unit' => $type['numeric'] ? $this->getUnit( $aliasEntry['unitRef'] ) : null,
							'value' => $value,
						);

						$existing =& $combinations->getValue( $key, null );
						if ( ! is_null( $existing ) )
						{
							$source = array(
								'section' => '4.10',
								'name' => $aliasElement['id'],
								'contextRef' => "{$aliasEntry['contextRef']} vs {$existing['context']}",
								'unitRef' => "{$aliasEntry['contextRef']} vs {$existing['unit']}",
								'value' => "{$value} vs {$existing['value']}",
							);

							$this->log()->warning( sprintf( "Duplicate item: %s", $this->log()->arrayToDescription( $source ) ) );
						}

						$combinations->addValue( $key, array(
							'name' => $aliasElement['id'],
							'context' => $aliasEntry['contextRef'],
							'unit' => $type['numeric'] ? $aliasEntry['unitRef'] : null,
							'value' => $value,
						) );

						$essenceAliasValues[ $aliasEntry['parent'] ]['alias'][ $alias ] = $value;
						$essenceAliasValues[ $aliasEntry['parent'] ]['contexts'][ $aliasEntry['contextRef'] ] = $aliasEntry['contextRef'];
						$essenceAliasValues[ $aliasEntry['parent'] ]['units'][ $aliasEntry['unitRef'] ] = $aliasEntry['unitRef'];
					}
				}
				else
				{
					// There is an essence fact so make sure the essence and alias facts are c-equal, u-equal, p-equal and v-equal
					foreach ( $essenceFact as $essenceEntryKey => $essenceEntry )
					{
						// Using PHP_ROUND_HALF_EVEN see XBRL 2.1 section 4.6.7.2
						$essenceValue = $type['numeric']
						 	? $this->getNumericPresentation( $essenceEntry )
							: $essenceEntry['value'];

						foreach ( $aliasFact as $aliasEntryKey => $aliasEntry )
						{
							if ( ! XBRL_Instance::isEmpty( $aliasEntry, 'nil' ) && filter_var( $aliasEntry['nil'], FILTER_VALIDATE_BOOLEAN ) ) continue;

							// The essence and alias should be p-equal
							if ( $essenceEntry['parent'] != $aliasEntry['parent'] )
							{
								/*
								$this->log()->instance_validation( "5.2.6.2.2", "The scope for the arc is not valid because the essence parent and the alias parent are not the same",
									array(
										'essence' => $essence,
										'alias' => $alias,
										'point' => '3',
									)
								);
								*/
								continue;
							}

							// check the essence and alias are C-Equal (by definition also S-Equal), P-Equal, U-Equal, V-Equal
							if ( $essenceEntry['contextRef'] != $aliasEntry['contextRef'] &&
								 ! XBRL_Equality::context_equal( $this->getContext( $essenceEntry['contextRef'] ), $this->getContext( $aliasEntry['contextRef'] ) )
							   )
							{
								/*
								$this->log()->instance_validation( "5.2.6.2.2", "The contexts on the essence and alias are not compatible",
									array(
										'essence' => $essence,
										'alias' => $alias,
										'point' => '3',
										'essence_context' => $essenceEntry['contextRef'],
										'alias_context' => $aliasEntry['contextRef'],
									)
								);
								*/
								continue;
							}

							if ( $essenceEntry['unitRef'] != $aliasEntry['unitRef'] &&
								 ! XBRL_Equality::unit_equal( $this->getUnit( $essenceEntry['unitRef'] ), $this->getUnit( $aliasEntry['unitRef'] ), $types, $this->getInstanceNamespaces() )
							   )
							{
								$this->log()->instance_validation( "5.2.6.2.2", "The units on the essence and alias are not compatible",
									array(
										'essence' => $essence,
										'alias' => $alias,
										'point' => '3',
										'essence_unit' => $essenceEntry['unitRef'],
										'alias_unit' => $aliasEntry['unitRef'],
									)
								);
								continue;
							}

							$value = $type['numeric']
								? $this->getNumericPresentation( $aliasEntry )
								: $aliasEntry['value'];

							// Create a key
							$key = array(
								'name' => $aliasElement['id'],
								'parent' => $aliasEntry['parent'],
								'context' => $this->getContext( $aliasEntry['contextRef'] ),
								'unit' => $type['numeric'] ? $this->getUnit( $aliasEntry['unitRef'] ) : null,
								'value' => $value,
							);

							$existing =& $combinations->getValue( $key, null );
							if ( ! is_null( $existing ) )
							{
								$source = array(
									'section' => '4.10',
									'name' => $aliasElement['id'],
									'contextRef' => "{$aliasEntry['contextRef']} vs {$existing['context']}",
									'unitRef' => "{$aliasEntry['contextRef']} vs {$existing['unit']}",
									'value' => "{$value} vs {$existing['value']}",
								);

								$this->log()->warning( sprintf( "Duplicate item: %s", $this->log()->arrayToDescription( $source ) ) );
							}

							$combinations->addValue( $key, array(
								'name' => $aliasElement['id'],
								'context' => $aliasEntry['contextRef'],
								'unit' => $type['numeric'] ? $aliasEntry['unitRef'] : null,
								'value' => $value,
							) );

							$essenceAliasValues[ $essenceEntry['parent'] ]['essencevalue'] = $essenceValue;
							$essenceAliasValues[ $essenceEntry['parent'] ]['essence'] = $essence;

							$essenceAliasValues[ $aliasEntry['parent'] ]['alias'][ $alias ] = $value;
							$essenceAliasValues[ $aliasEntry['parent'] ]['contexts'][ $aliasEntry['contextRef'] ] = $aliasEntry['contextRef'];
							$essenceAliasValues[ $aliasEntry['parent'] ]['units'][ $aliasEntry['unitRef'] ] = $aliasEntry['unitRef'];
						}
					}
				}
			}

			// If an essence fact exists then check its values are consistent with the alias value(s)
			// If an essence fact does not exist then create one based on the values in the $inferredParents
			foreach ( $essenceAliasValues as $parentKey => $details )
			{
				if ( isset( $details['essencevalue'] ) )
				{
					foreach ( $details['alias'] as $alias => $value )
					{
						if ( $value === $details['essencevalue'] ) continue;
						$this->log()->instance_validation( "5.2.6.2.2", "Essence alias values do not match",
							array(
								'essence' => $details['essence'],
								'alias' => $alias,
								'essence_value' => $details['essencevalue'],
								'alias_value' => "'$value'",
							)
						);
					}
				}
				else
				{
					// echo "Need to create an inferred fact\n";
					// Create a namespace prefix as known in the instance document for consistency
					// This gets the namespace for the essence element looks up the corresponding prefix in the instance document
					$namespace = $this->getPrefixForNamespace( $essenceTaxonomy->getNamespaceForPrefix( $essenceTaxonomy->getPrefix() ) );
					$newEntry = array(
						'taxonomy_element' => $essenceElement,
						'namespace' => $namespace,
					);

					// All the values must be the same if a value for the essence is to be inferred
					$diff = array_diff( $details['alias'], $details['alias'] );
					if ( ! $diff ) continue;

					$this->log()->instance_validation( "5.2.6.2.2", "The values of all aliases should all be the same for an essence value to be inferre",
						array(
							'essence' => $essence,
							'alias' => $this->log()->arrayToDescription( $details['alias'] ),
						)
					);

					$newEntry['contextRef'] = reset( $details['contexts'] );
					$newEntry['unitRef'] = reset( $details['units'] );

					$this->addElement( $essence, $newEntry );
				}
			}
		}
	}
185997
private function validateRequiresElementArcs( XBRL_Types &$types )
	{

		$arcs = $this->getInstanceTaxonomy()->getRequireElementsList();
		if ( ! $arcs ) return true;

		foreach ( $arcs as $from => $targets )
		{
			// echo "$from";

			// If the $from exists then the $to exists
			$parts = parse_url( $from );
			if ( ! isset( $parts['path'] ) || ! isset( $parts['fragment'] ) ) continue;

			$fromTaxonomy = $this->getInstanceTaxonomy()->getTaxonomyForXSD( $parts['path'] );
			if ( ! $fromTaxonomy )
			{
				$this->log()->instance_validation( "5.2.6.2.4", "The taxonomy of the source does not exist in the DTS",
					array(
						'from' => $from,
					)
				);
				continue;
			}

			$fromElement = $fromTaxonomy->getElementById( $parts['fragment'] );
			if ( ! $fromElement )
			{
				$this->log()->instance_validation( "5.2.6.2.4", "The concept of the source does not exist in the DTS",
					array(
						'from' => $from,
					)
				);
				continue;
			}

			// Look for the fact in the instance document
			$fromFact = $this->getElement( $fromElement['id'] );

			// If the $from does not exist there is noting else to do
			if ( ! $fromFact ) continue;

			foreach ( $targets as $target => $details )
			{
				// echo " -> $target\n";

				$parts = parse_url( $target );
				if ( ! isset( $parts['path'] ) || ! isset( $parts['fragment'] ) ) continue;

				$toTaxonomy = $this->getInstanceTaxonomy()->getTaxonomyForXSD( $parts['path'] );
				if ( ! $toTaxonomy )
				{
					$this->log()->instance_validation( "5.2.6.2.4", "The taxonomy of the target does not exist in the DTS",
						array(
							'from' => $from,
						)
					);
					continue;
				}

				$toElement = $toTaxonomy->getElementById( $parts['fragment'] );
				if ( ! $toElement )
				{
					$this->log()->instance_validation( "5.2.6.2.4", "The concept of the target does not exist in the DTS",
						array(
							'to' => $to,
						)
					);
					continue;
				}

				// Look for the fact in the instance document
				$toFact = $this->getElement( $toElement['id'] );

				// If the $from does not exist there is noting else to do
				if ( $toFact ) continue;

				// The $from exist but the $to does not so report the error.
				$this->log()->instance_validation( "5.2.6.2.4", "The required source fact exists but the target one does not exist.",
					array(
						'from' => $from,
						'to' => $target,
					)
				);

			}
		}
	}
120569
public static function getValidType($type, $xsdTypesPath = null, $fallback = null)
    {
        return XsdTypes::instance($xsdTypesPath)->isXsd(str_replace('[]', '', $type)) ? $fallback : $type;
    }
1202250
public function indexXDT( &$types, &$node, &$element )
	{
		$xbrldtAttributes = $node->attributes( XBRL_Constants::$standardPrefixes[ STANDARD_PREFIX_XBRLDT ] );
		if ( property_exists( $xbrldtAttributes, 'typedDomainRef' ) )
		{
			$element['typedDomainRef'] = (string) $xbrldtAttributes->typedDomainRef;
		}

		if ( ! empty( $element['substitutionGroup'] ) )
		{
			$id = $element['id'];
			$name = $element['name'];

			if ( $types->resolveToSubstitutionGroup( $element['substitutionGroup'], array( XBRL_Constants::$xbrldtDimensionItem ) ) )
			{
				$this->elementDimensions[] = $name;
			}
			else if ( $types->resolveToSubstitutionGroup( $element['substitutionGroup'], array( XBRL_Constants::$xbrldtHypercubeItem ) ) )
			{
				$this->elementHypercubes[] = $name;
			}
			else if ( $types->resolveToSubstitutionGroup( $element['substitutionGroup'], array( XBRL_Constants::$xlArc ) ) )
			{
				$this->elementArcTypes[] = $name;
			}
			else if ( $types->resolveToSubstitutionGroup( $element['substitutionGroup'], array( XBRL_Constants::$xlExtended ) ) )
			{
				$this->elementLinkTypes[] = $name;
			}
			// else if ( $element['type'] == XBRL_Constants::$enumItemType || $element['type'] == XBRL_Constants::$enumSetItemType )
			else if ( $types->resolvesToBaseType( $element['type'], array( XBRL_Constants::$enumItemType, XBRL_Constants::$enumSetItemType ), false ) )
			{
				// Record that this element is an extensible enumeration concept
				$this->enumerations[  $id ] = $id;

				// Make sure there is a linkrole and domain attribute
				$enumAttributes = $node->attributes( XBRL_Constants::$standardPrefixes[ STANDARD_PREFIX_ENUMERATIONS ] );

				if ( property_exists( $enumAttributes, 'domain' ) )
				{
					$element['enumDomain'] = (string)$enumAttributes['domain'];
				}
				else
				{
					if ( $this->isValidating() )
					{
						$this->log()->taxonomy_validation( "Extensible enumerations", "The extensible concept does not include a domain",
							array(
								'id' => $id,
								'name' => $name,
								'type' => $element['substitutionGroup'],
								'error' => 'enumte:MissingDomainError'
							)
						);
					}
				}

				if ( property_exists( $enumAttributes, 'linkrole' ) )
				{
					$element['enumLinkrole'] = (string)$enumAttributes['linkrole'];
				}
				else
				{
					if ( $this->isValidating() )
					{
						$this->log()->taxonomy_validation( "Extensible enumerations", "The extensible concept does not include a linkrole",
							array(
								'id' => $id,
								'name' => $name,
								'type' => $element['substitutionGroup'],
								'error' => 'enumte:MissingLinkRoleError'
							)
						);
					}
				}

				$element['enumHeadUsable'] = property_exists( $enumAttributes, 'headUsable' )
					? filter_var( $enumAttributes['headUsable'], FILTER_VALIDATE_BOOLEAN )
					: false;
			}
		}

	}
1264550
public function equals(Key $key, $prefix) {
        $prefix .= ': Index (' . $this->getName() . '):';
        $errors = [];
        if($key->getName() !== $this->getName()) {
            throw new \Exception('Comparing Incomparable columns');
        }
        if($key->getType() !== $this->getType()) {
            $errors[] = $prefix . 'Type Does Not Match:' . "\n" . $key->getType() . "\n" . $this->getType();
        }
        $diff = array_diff($key->getColumns(), $this->getColumns());
        if(!empty($diff)) {
            $errors[] = $prefix . 'Extra Columns: ' . "\n" . implode("\n", $diff);
        }
        $diff = array_diff($this->getColumns(), $key->getColumns());
        if(!empty($diff)) {
            $errors[] = $prefix . 'Missing Columns: ' . "\n" . implode("\n", $diff);
        }
        return $errors;
    }
289561
public static function compare(LocaleInterface $x, LocaleInterface $y)
    {
        return strcmp($x->endonymSortable(), $y->endonymSortable());
    }
1042373
public function Equals( $obj )
	{
		if ( ! $obj instanceof QNameValue )
		{
			return false;
		}

		/**
		 * @var QNameValue $other
		 */
		$other = $obj;
		// // BMS 2017-09-13 The xfi test fact-dimension-s-equal2 V18 requires this comparison
		// return (string)$this == (string)$other;
		return $this->LocalName == $other->LocalName && $this->NamespaceUri == $other->NamespaceUri;
	}
981212
public function getValueType()
	{
		if ( $this->_value instanceof IXmlSchemaType )
		{
			return Type::FromValue( $this->_value );
		}
		else
		{
			$qn = $this->_xmlType->QualifiedName;
			$xmlType = $qn->prefix ? "{$qn->prefix}:{$qn->localName}" : "{$qn->localName}";
			return Type::XmlTypeToType( $xmlType );
		}

		return Type::FromValue( $this->_value );
	}
1033542
public <T> Local<T> getThis(TypeId<T> type) {
        if (thisLocal == null) {
            throw new IllegalStateException("static methods cannot access 'this'");
        }
        return coerce(thisLocal, type);
    }