public static function fromIterator( $context, $sourceIterator, $mode, $nonNilOnly = false )
	{
		if ( ! $sourceIterator instanceof XPath2NodeIterator )
		{
			return EmptyIterator::$Shared;
		}

		$test = new NodeTest( SequenceTypes::$Element );
		$iterator = $mode == XFI_TUPLE_ITEMS || $mode == XFI_TUPLE_TUPLES
			? ChildNodeIterator::fromNodeTest($context, $test, $sourceIterator )
			: ChildOverDescendantsNodeIterator::fromParts( $context, array( $test ), $sourceIterator );

		$result = new InstanceFactsIterator( $context );
		$result->nonNilOnly = $nonNilOnly;
		$result->iterator = $iterator;

		if ( $mode == XFI_INSTANCE_ALL_FACTS )
		{
			$result->substitutionGroups = array_merge( InstanceFactsIterator::$itemSubstitutionGroup, InstanceFactsIterator::$tupleSubstitutionGroup );
		}
		else if ( $mode == XFI_INSTANCE_ITEMS || $mode == XFI_TUPLE_ITEMS )
		{
			$result->substitutionGroups = InstanceFactsIterator::$itemSubstitutionGroup;
		}
		else if ( $mode == XFI_INSTANCE_TUPLES || $mode == XFI_TUPLE_TUPLES )
		{
			$result->substitutionGroups = InstanceFactsIterator::$tupleSubstitutionGroup;
		}

		return $result;
	}