Get the concept aspect value
@param Formula $variableSet
@param array $evaluationResult
@param \XBRL_Log $log
@return DOMXPathNavigator
186384
public function getValue( $variableSet, $evaluationResult, $log )
	{
		$numerators = array();
		$denominators = array();
		$unitRef = "";

		// Create a list of numerators and denominators
		if ( $this->augment )
		{
			$this->getFactorsFromSource( $this->source, $variableSet, $evaluationResult, $log, $numerators, $denominators, $unitRef );
		}

		foreach ( $this->multiplyBy as $numerator )
		{
			$hasMeasure = isset( $numerator['measure'] ) && $numerator['measure'];

			if ( ! $hasMeasure && isset( $numerator['source'] ) )
			{
				$this->getFactorsFromSource( $numerator['source'], $variableSet, $evaluationResult, $log, $numerators, $denominators );
			}

			if ( $hasMeasure )
			{
				// This is an expression that needs evaluating
				$result = $this->evaluateXPath( $variableSet, "{$numerator['measure']} cast as xs:string", $evaluationResult['vars'] );
				$numerators[] = $result->getValue();
			}
		}

		foreach ( $this->divideBy as $denominator )
		{
			$hasMeasure = isset( $denominator['measure'] ) && $denominator['measure'];

			if ( ! $hasMeasure && isset( $denominator['source'] ) )
			{
				$this->getFactorsFromSource( $denominator['source'], $variableSet, $evaluationResult, $log, $denominators, $numerators );
			}

			if ( $hasMeasure )
			{
				// This is an expression that needs evaluating
				$result = $this->evaluateXPath( $variableSet, "{$denominator['measure']} cast as xs:string", $evaluationResult['vars'] );
				$denominators[] = $result->getValue();
			}
		}

		// Cancel mutual numerators and denominators
		$this->cancel( $numerators, $denominators );

		// Return an array appropriately structured
		$result = array();
		if ( ! $denominators )
		{
			if ( count( $numerators ) == 1 )
			{
				$result = reset( $numerators );
			}
			else
			{
				$result = array( 'measures' => $numerators );
			}
		}
		else
		{
			$result = array(
				'divide' => array( 'numerator' => $numerators, 'denominator' => $denominators )
			);
		}

		if ( ! $unitRef ) $unitRef = "unit";
		return array( $unitRef => $result );
	}
758706
public function toQuery( $variableSet, $factVariableBinding )
	{
		$result = array();

		if ( count( $this->filters ) == 0 )
		{
			return array( "false()" );
		}

		foreach ( $this->filters as $filter )
		{
			$filter->inBoolean = true;

			$query = $filter->toQuery( $variableSet, $factVariableBinding );
			if ( $filter->complement )
			{
				$query = "not($query)";
			}
			$result[] = $query;
		}

		return $result;
	}
357015
public function toQuery( $variableSet, $factVariableBinding )
	{
		$result = parent::toQuery( $variableSet, $factVariableBinding );
		$query = "(" . implode( " or ", $result ) . ")";
		if ( $this->complement )
		{
			$query = "not{$query}";
		}
		return $query;
	}
1063664
public function validate( $variableSet, $nsMgr )
	{
		$log = \XBRL_Log::getInstance();

		// If there is no source then concept MUST be explicitly declared
		if ( is_null( $this->source ) )
		{
			if ( is_null( $this->conceptRule ) )
			{
				$log->formula_validation( "Tuple", "If there is no source then a concept aspect rule MUST be explicitly declared but is not provided",
					array(
						'formula' => $this->label,
						'error' => 'xbrlfe:missingConceptRule'
					)
				);
			}

			// Create a qname from either the qname or the expression
			/**
			 * @var QName $qname
			 */
			$qname = null;
			if ( $this->conceptRule['qnameExpression'] )
			{
				foreach ( $this->conceptRule['qnameExpression'] as $qnameExpression )
				{
					// Check any variables in the expression are valid
					$expression = XPath2Expression::Compile( $qnameExpression, $this->nsMgr );
					$variableRefs = $expression->getParameterQNames();
					foreach ( $variableRefs as $variableQName )
					{
						if ( ! isset( $this->variablesByQName[ $variableQName->clarkNotation() ] ) )
						{
							$log->formula_validation( "Concept rule", "The variable reference in the concept rule qname expression is not to a valid variable",
								array(
									'formula' => $this->label,
									'variable reference' => $variableQName->clarkNotation(),
									'error' => 'xbrlfe:conceptExpressionInvalid'
								)
							);
						}
					}
				}
			}
			else
			{
				$qname = new QName( $this->conceptRule['qname'][0]['originalPrefix'], $this->conceptRule['qname'][0]['namespace'], $this->conceptRule['qname'][0]['name'] );

				// BMS 2018-01-05 Now not sure why these tests are needed.
	 			// Next find out if the qname refers to a variable.  If it does look for a filter that defines a concept
	 			// Begin by assuming the qname refers to a taxonomy element
	 			$concept = $qname;
	 			if ( isset( $this->variablesByQName[ $concept->clarkNotation() ] ) )
	 			{
	 				/**
	 				 * @var ConceptName $selectedFilter
	 				 */
	 				$selectedFilter = null;
	 				foreach ( $this->variablesByQName[ $concept->clarkNotation() ]->filters as $filter )
	 				{
	 					if ( ! $filter instanceof ConceptName ) continue;
	 					$selectedFilter = $filter;
	 					break;
	 				}

	 				if ( $selectedFilter )
	 				{
						$concept = null;
						$totalFilters = count( $selectedFilter->qnames ) + count( $selectedFilter->qnameExpressions );
						if ( $totalFilters == 1 )
						{
							// It's one of these
							foreach ( $selectedFilter->qnames as $filterQName )
							{
								$concept = qname( $filterQName );
								$taxonomy = $this->xbrlTaxonomy->getTaxonomyForNamespace( $concept->namespaceURI );
								$concept->prefix = $taxonomy->getPrefix();
							}

							if ( ! $concept )
							{
								foreach ( $selectedFilter->qnameExpressions as $filterQNameExpression )
				 				{
									$result = $this->evaluateXPath( $this, $this->conceptRule->$filterQNameExpression );
									$concept = new QName( $result->Prefix, $result->NamespaceUri, $result->LocalName );
			 					}
							}
						}

						if ( $totalFilters != 1 || ! $concept )
						{
							$log->formula_validation( "Formula", "There is no formula source but the concept aspect rule does not define a reference to a schema element",
								array(
									'formula' => $this->label,
									'error' => 'xbrlfe:missingConceptRule'
								)
							);
						}
	 				}
	 				else
	 				{
	 					// If the concept references a variable and there is no filter then the
	 					// the concept cannot be resolved statically.
	 					$concept = null;
	 				}
				}

				if ( $concept )
				{
					// BMS 2017-12-24 Move the following tests here because surely they are only relevant when there is no formula source
					$types = \XBRL_Types::getInstance();
					$conceptElement = $this->xbrlTaxonomy->getElementByName( $concept->localName );
					// Or could do it this way
					// $conceptElement = $types->getElement( $this->conceptRule['qname'][0]['name'], $this->conceptRule['qname'][0]['originalPrefix'] );
					// $isNumeric = $types->resolvesToBaseType( $conceptElement['types'][0], array( 'xs:decimal', 'xsd:decimal' ) );
					if ( ! $conceptElement )
					{
						$log->formula_validation( "Tuple", "The concept provided by the concept aspect rule is not a valid schema element",
							array(
								'formula' => $label,
								'error' => 'xbrlfe:missingConceptRule'
							)
						);
					}

					$isTuple = $types->resolveToSubstitutionGroup( $conceptElement['substitutionGroup'], array( 'xbrli:tuple' ) );
					if ( ! $isTuple )
					{
						$log->formula_validation( "Tuple", "The concept provided by the concept aspect rule is not a tuple",
							array(
								'formula' => $label,
								'error' => 'xbrlfe:invalidConceptRule'
							)
						);
					}
				}
			}
		}
		else // $source is not null
		{
			$sourceQName = new QName( $this->source['originalPrefix'], $this->source['namespace'], $this->source['name'] );

			// If the if the source is not the uncovered qname make sure the referenced variable exists
			if ( $sourceQName->namespaceURI != \XBRL_Constants::$standardPrefixes[ STANDARD_PREFIX_FORMULA ] ||
				 $sourceQName->localName != "uncovered" )
			{
				if ( ! isset( $this->variablesByQName[ $sourceQName->clarkNotation() ] ) ||
					 ! $this->variablesByQName[ $sourceQName->clarkNotation() ] instanceof FactVariable
				)
				{
					$log->formula_validation( "Formula", "",
						array(
							'concept' => $sourceQName->prefix ? "{$sourceQName->prefix}:{$sourceQName->localName}" : $sourceQName->localName,
							'formula' => $this->label,
							'error' => 'xbrlfe:nonexistentSourceVariable',
						)
					);
				}

				/**
				 * Look for the variable
				 * @var FactVariable $variable
				 */
				$variable = $this->variablesByQName[ $sourceQName->clarkNotation() ];
				if ( $variable->bindAsSequence )
				{
					// TODO Should check the XPath implied by the fallback value but, for now,
					//	    copy Arelle and fail if there is any fallback value
					$log->formula_validation( "Formula", "Formula source is a fact variable that binds as a sequence",
						array(
							'formula' => $this->label,
							'source' => $sourceQName->prefix ? "{$sourceQName->prefix}:{$sourceQName->localName}" : $sourceQName->localName,
							'error' => 'xbrlfe:defaultAspectValueConflicts',
						)
					);
				}
			}
		}

		$sources = $this->getAspectSources();
		foreach ( $sources as $ruleName => $source )
		{
			if ( $source['namespace'] == \XBRL_Constants::$standardPrefixes[ STANDARD_PREFIX_FORMULA ] && $source['name'] == 'uncovered' ) continue;

			$sourceQName = new QName( $source['originalPrefix'], $source['namespace'], $source['name'] );
			/**
			 * Look for the variable
			 * @var FactVariable $variable
			 */
			$variable = $this->variablesByQName[ $sourceQName->clarkNotation() ];
			if ( ! $variable->fallbackValue ) continue;

			// TODO Should check the XPath implied by the fallback value but, for now,
			//	    copy Arelle and fail if there is any fallback value
			$log->formula_validation( "Formula aspects", "Formula source is a fact variable that has a fallback value",
				array(
					'formula' => $this->label,
					'rule' => $ruleName,
					'error' => 'xbrlfe:bindEmptySourceVariable',
				)
			);
		}

		return true;
	}
450062
public function evaluateResult()
	{
		// \XBRL_Log::getInstance()->info( "Process value assertion" );

		// Although I cannot find any reference to it in the documentation, it seems that only unique derived facts
		// should be compared.  Uniquenesss in this case appears to be derived facts that have the same contributing variables.
		// Conformance test 34120 V-13 has this issue.  In this test there are 7 facts produced but 1 is a duplicates.
		// The TupleDictionary works well for this scenario
		if ( ! $this->pastEvaluationHashes ) $this->pastEvaluationHashes = new \TupleDictionary();

		try
		{
			// Check all variables are not all fallback and that preconditions are met
			if ( ! parent::evaluateResult() )
			{
				return;
			}

			$vars = $this->getBindingsAsVars();

			$varsCopy = $vars;
			foreach ( $varsCopy as $name => /** @var DOMXPathNavigator $var */ $var )
			{
				$varsCopy[ $name ] = $var instanceof DOMXPathNavigator
					? $var->getUnderlyingObject()->getNodePath()
					: ( $var instanceof XPath2NodeIterator // Should the list of nodes and or values in the iterator be added?
							? $var
							: ( $var instanceof Undefined
									? ""
									: ( $var instanceof IXmlSchemaType
										? $var
										: ( is_object( $var ) ? $var->getTypedValue() : $var ) ) )
					  );
			}

			if ( $this->pastEvaluationHashes->exists( $varsCopy ) )
			{
				return;
			}

			$this->pastEvaluationHashes->addValue( $varsCopy, 1 );
			$result = CoreFuncs::BooleanValue( parent::evaluateXPathExpression( $this, $this->testXPath2Expression, $vars ) );

			// This can used by message expressions
			$vars[ "{{$this->namespace}}test-expression" ] = $this->test;
			$evaluationResult = array( 'vars' => $vars, 'lastFactBinding' => $this->getLastFactBinding() );
			$evaluationResult['uncoveredAspectFacts'] = $evaluationResult['lastFactBinding'] instanceof FactVariableBinding
				? $evaluationResult['lastFactBinding']->uncoveredAspectFacts
				: array();

			if ( $result instanceof CoreFuncs::$True )
			{
				$this->satisfied[] = $evaluationResult;
				$this->generatedSatisifiedMessages = array_merge( $this->generatedSatisifiedMessages, $this->processMessages( $this->satisfiedMessages, $vars ) );
			}
			else if ( $result instanceof CoreFuncs::$False )
			{
				$this->unsatisfied[] = $evaluationResult;
				$this->generatedUnsatisifiedMessages = array_merge( $this->generatedSatisifiedMessages, $this->processMessages( $this->unsatisfiedMessages, $vars ) );
			}
			else
			{
				\XBRL_Log::getInstance()->valueassertion_validation( "Valid Assertion result", "Expects a true or false evaluation result",
					array(
						'value type' => '',
						'text' => $this->test
					)
				);
			}
		}
		catch( \Exception $ex )
		{
			throw $ex;
		}
	}
296074
public static function EvaluateWithArgAndResolver( $xpath2, $nsResolver, $arg )
	{
		return XPath2Expression::Compile( $xpath2, $nsResolver)->EvaluateWithProperties( null, $arg );
	}
554303
public String evaluate(Object pContext,
                           VariableResolver pResolver,
                           Map functions,
                           String defaultPrefix,
                           Logger pLogger)
            throws ELException {
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < mElements.length; i++) {
            Object elem = mElements[i];
            if (elem instanceof String) {
                buf.append((String) elem);
            } else if (elem instanceof Expression) {
                Object val =
                        ((Expression) elem).evaluate(pContext,
                                pResolver,
                                functions,
                                defaultPrefix,
                                pLogger);
                if (val != null) {
                    buf.append(val.toString());
                }
            }
        }
        return buf.toString();
    }
78632
public function toQuery( $variableSet, $factVariableBinding )
	{
		// return null;
		$variable = $this->variable['originalPrefix']
			? "{$this->variable['originalPrefix']}:{$this->variable['name']}"
			: $this->variable['name'];

		if ( $this->boundary == "start" ||  $this->boundary == "end" )
		{
			return "(xfi:period(.)[ if (xfi:is-instant-period(.) and xfi:is-start-end-period(xfi:period(\$$variable))) then (xfi:period-instant(.) eq xfi:period-{$this->boundary}(xfi:period(\$$variable))) else fn:false() ])";
		}
		else
		{
			return "fn:false()";
		}
	}
1036128
private function BindExpr( $vars )
	{
		/**
		 * @var XPath2RunningContext $runningContext
		 */
		$runningContext = new XPath2RunningContext();

		/**
		 * @var ReferenceLink[] $variables
		 */
		$variables = null;
		$variableValues = null;
		if ( ! is_null( $vars ) && ! empty( $vars ) )
		{
			/**
			 * @var array[ReferenceLink] $variables
			 */
			$variables = array(); // new ReferenceLink[$vars.Count];
			$variableValues = array(); // new object[$vars.Count];
			// $array = $vars; // new KeyValuePair<QName, object>[$vars.Count];
			$array = array();
			foreach ( $vars as $key => $value )
			{
				$variables[] = $runningContext->NameBinder->PushVar( $key );
				$variableValues[] = $value;
			}
		}

		$this->context->RunningContext = $runningContext;
		$this->context->availableCollections = isset( $vars['availableCollections'] ) ? $vars['availableCollections'] : array();
		$this->context->defaultCollection = isset( $vars['defaultCollection'] ) ? $vars['defaultCollection'] : null;

		$this->exprTree->Bind();

		/**
		 * @var object[] $datapool
		 */
		$dataPool = array(); // new object[ $runningContext->NameBinder->getLength() ];
		if ( ! is_null( $variables ) )
		{
			for ( $k = 0; $k < count( $variables ); $k++ )
			{
				$variables[ $k ]->Set( $dataPool, $this->PrepareValue( $variableValues[ $k ] ) );
			}
		}
		return $dataPool;
	}
1248655
private Object evaluateExpressionInternal(String expression, String attrName, PageContext pageContext)
            throws JspException
    {
        if (logger.isDebugEnabled())
            logger.debug("evaluate expression=\"" + expression + "\"");

        Object result = null;
        try {
            VariableResolver vr = ImplicitObjectUtil.getReadVariableResolver(pageContext);
            result = getExpressionEvaluator().evaluateStrict(expression, vr);
        }
        catch (ExpressionEvaluationException ee) {
            // if there is an expression evaluation error set the error and return null
            if (logger.isWarnEnabled())
                logger.warn(Bundle.getString("Tags_ExpressionEvaluationFailure", expression));

            // create the expression info an add it to the error tracking
            EvalErrorInfo info = new EvalErrorInfo();
            info.evalExcp = ee;
            info.expression = expression;
            info.attr = attrName;
            info.tagType = _tag.getTagName();

            // report the error
            _tag.registerTagError(info);
            return null;
        }
        catch (Exception e) {
            String s = Bundle.getString("Tags_ExpressionEvaluationException", new Object[]{expression, e.toString()});
            _tag.registerTagError(s, e);
            return null;
        }

        if (logger.isDebugEnabled()) logger.debug("resulting object: " + result);
        return result;
    }
803092
public function getValue( $variableSet, $evaluationResult, $log )
	{
		// Should already have been validated that if there is no source, there MUST be a complete entity identifier aspect is defined.
		if ( $this->source )
		{
			$sourceFact = $variableSet->getSourceFact( $this->source, $evaluationResult, ASPECT_ENTITY_IDENTIFIER, $log );
			if ( is_null( $sourceFact ) )
			{
				$source = is_array( $this->source ) ? "{$this->source['originalPrefix']}:{$this->source['name']}" : $this->source;
				$log->formula_validation( "Formula", "Invalid or missing source fact for entity identifier",
					array(
						'source' => $source,
						'error' => 'xbrlfe:undefinedSAV'
					)
				);
			}

			$contextRef = FactValues::getContextRef( $sourceFact );
			if ( ! $contextRef ) return null;
			$context = $variableSet->xbrlInstance->getContext( $contextRef );
			$identifier = isset( $context['entity']['identifier'] )
				? $context['entity']['identifier']
				: array();
		}

		if ( $this->scheme )
		{
			$result = $this->evaluateXPath( $variableSet, "{$this->scheme} cast as xs:string", $evaluationResult['vars'] );
			$identifier['scheme'] = is_object( $result ) ? $result->getValue() : $result;
		}

		if ( $this->value )
		{
			$result = $this->evaluateXPath( $variableSet, "({$this->value}) cast as xs:string", $evaluationResult['vars'] );
			$identifier['value'] = is_object( $result ) ? $result->getValue() : $result;
		}

		return $identifier;
	}
1162042
public function getValue( $variableSet, $evaluationResult, $log )
	{
		$aspect = $variableSet->aspectModel == 'dimensional'
			? ( $this->occ == 'segment' ? ASPECT_NON_XDT_SEGMENT : ASPECT_NON_XDT_SCENARIO )
			: ( $this->occ == 'segment' ? ASPECT_COMPLETE_SEGMENT : ASPECT_COMPLETE_SCENARIO );

		$sourceFact = $variableSet->getSourceFact( $this->source, $evaluationResult, $aspect, $log );
		if ( ! $sourceFact ) return null;
		$contextRef = FactValues::getContextRef( $sourceFact );
		if ( ! $contextRef ) return null;
		$context = $variableSet->xbrlInstance->getContext( $contextRef );
		// $component = isset( $context['entity'][ $this->occ ]['member'] )
		// 	? $context['entity'][ $this->occ ]['member']
		// 	: array();
		$component = array();
		foreach ( $this->occList as $member )
		{
			$component[] = array( 'name' => $member, 'member' => '' );
		}

		return $component;
	}
1179846
public function getAspectsCovered( $variableSet, $factVariableBinding )
	{
		$result = array();

		foreach ( $this->filters as $filter )
		{
			if ( ! $filter->cover ) continue;
			$result = array_merge( $result, $filter->getAspectsCovered( $variableSet, $factVariableBinding ) );
		}

		return $result;
	}
604453
public function toQuery( $variableSet, $factVariableBinding )
	{
		/**
		 * These are the arguments to the xfi:concept-relationships function
	     * #source
		 * #linkrole
		 * #arcrole
		 * #axis
		 * #generations
		 * #linkname
		 * #arcname
		 */

		$source = $this->variable
					? ( "fn:node-name(" . ( $this->variable['originalPrefix'] ? "\${$this->variable['originalPrefix']}:$this->variable['name']" : "\${$this->variable['name']}" ) . ")" )
					: ( $this->qnameExpression
							? $this->qnameExpression
							: "QName('" . qname($this->qname, $variableSet->nsMgr->getNamespaces())->namespaceURI . "', '" . qname($this->qname, $variableSet->nsMgr->getNamespaces())->localName . "')"
					  );

		$linkrole = $this->linkrole
					? "'{$this->linkrole}'"
					: ( $this->linkroleExpression
							? $this->linkroleExpression
							: "()"
					  );

		$arcrole = $this->arcrole
					? "'{$this->arcrole}'"
					: ( $this->arcroleExpression
							? $this->arcroleExpression
							: "()"
					  );

		$axis = "{$this->axis}";
		$generations = $this->generations ? $this->generations : "()";

		$linkname = $this->linkname
					? "'{$this->linkname}'"
					: ( $this->linknameExpression
							? $this->linknameExpression
							: "()"
					  );

		$arcname = $this->arcname
					? "'{$this->arcname}'"
					: ( $this->arcnameExpression
							? $this->arcnameExpression
							: "()"
					  );

		$test = $this->test
					? $this->test
					: "true()";

		// Alternative line end goes here (for query formatting)
		$le = "";

		$query = "( $le" .
				 "	( $le" .
				 "		some \$relationship in $le" .
				 "			xfi:concept-relationships( $le" .
				 "				$source, $le" .
				 "				$linkrole, $le" .
				 "				$arcrole, $le" .
				 "				" . str_replace( "-or-self", "", "'$axis'" ) . ",$le" .
		//		 "				fn:replace($axis,'-or-self',''), $le" .
				 "				$generations, $le" .
				 "				$linkname, $le" .
				 "				$arcname $le" .
				 "			) $le" .
				 "		satisfies $le" .
				 "			( $le" .
				 "				\$relationship[$test] and $le" .
				 "				(fn:node-name(.) eq $le" .
             	 "					( $le" .
             	 "						if (matches('$axis','ancestor|parent')) $le" .
              	 "						then xfi:relationship-from-concept(\$relationship) $le" .
              	 "						else xfi:relationship-to-concept(\$relationship) $le" .
              	 "					) $le" .
              	 "				) $le" .
              	 "			) $le" .
              	 "  ) $le";

		$clause1 = "" .
				 "	or $le" .
				 "	( $le" .
		//		 "		fn:starts-with($axis,'sibling') and $le" .
				 "		fn:empty( $le" .
				 "			xfi:concept-relationships( $source, $linkrole, $arcrole, 'parent', 1, $linkname, $arcname) $le" .
				 "		) and $le" .
				 "		fn:empty( $le" .
				 "			xfi:concept-relationships( fn:node-name(.), $linkrole, $arcrole, 'parent', 1, $linkname, $arcname) $le" .
				 "		) and $le" .
				 "		fn:exists( $le" .
				 "			xfi:concept-relationships( fn:node-name(.), $linkrole, $arcrole, 'child', 1, $linkname, $arcname) $le" .
				 "		) and $le" .
				 "		(fn:node-name(.) ne $source) $le" .
				 "	) $le";

		$clause2 = "" .
				 "	or $le" .
				 "	( $le" .
		//		 "		fn:ends-with($axis,'-or-self') $le" .
		//		 " 		and $le" .
		//		 "		( $le" .
				 "			if ( QName('http://www.xbrl.org/2008/function/instance','root') eq $source) $le" .
				 "			then $le" .
				 "			( $le" .
				 "				fn:empty( $le" .
				 "					xfi:concept-relationships( fn:node-name(.), $linkrole, $arcrole, 'parent', 1, $linkname, $arcname) $le" .
				 "				) and $le" .
				 "				fn:exists( $le" .
				 "					xfi:concept-relationships( fn:node-name(.), $linkrole, $arcrole, 'child', 1, $linkname, $arcname) $le" .
				 "				) $le" .
				 "			) $le" .
				 "			else $le" .
				 "			( $le" .
				 "				fn:node-name(.) eq $source $le" .
				 "			) $le" .
		//		 "		) $le" .
				 "  ) $le";

		$query = $query . ( \XBRL::startsWith( $axis, 'sibling' ) ? $clause1 : "" ) . ( \XBRL::endsWith( $axis, '-or-self' ) ? $clause2 : "" );
		$query .= ") $le";
		if ( empty( $le ) )
		{
			$query = preg_replace( "/\s\t+/", " ", $query );
		}
		echo $query;
		return $query;
	}
753056
public function getSourceFactWithErrorLogging( $source, $evaluationResult, $aspect, $log )
	{
		$result = $this->getSourceFact( $source, $evaluationResult, $aspect, $log );
		if ( $result ) return $result;

		$log->formula_validation( "Formula", "Invalid or missing source fact",
			array(
				'source' => $source,
				'error' => 'xffe:InvalidSource'
			)
		);
	}
271100
public function getAdditionalNamespaces( $variableSet, $evaluationResult )
	{
		$namespaces = array();

		foreach ( $this->multiplyBy as $numerator )
		{
			if ( ! isset( $numerator['measure'] ) || ! $numerator['measure'] ) continue;

			// This is an expression that needs evaluating
			$result = $this->evaluateXPath( $variableSet, "{$numerator['measure']}", $evaluationResult['vars'] );
			if ( $result instanceof XPath2Item )
			{
				$result = $result->getTypedValue();
			}
			// Should report an error here
			if ( ! $result instanceof QNameValue ) continue;
			$namespaces[ $result->Prefix ] = $result->NamespaceUri;
		}

		foreach ( $this->divideBy as $denominator )
		{
			if ( ! isset( $denominator['measure'] ) || ! $denominator['measure'] ) continue;

			// This is an expression that needs evaluating
			$result = $this->evaluateXPath( $variableSet, "{$denominator['measure']}", $evaluationResult['vars'] );
			if ( $result instanceof XPath2Item )
			{
				$result = $result->getTypedValue();
			}
			// Should report an error here
			if ( ! $result instanceof QNameValue ) continue;
			$namespaces[ $result->Prefix ] = $result->NamespaceUri;
		}

		return $namespaces;
	}
272217
public function validate( $variableSet, $nsMgr )
	{
		if ( isset( $this->test ) && ! empty( $this->test ) )
		{
			try
			{
				$expression = XPath2Expression::Compile( $this->test, $nsMgr );
				$this->testXPath2Expression = $expression;
			}
			catch ( Exception $ex )
			{
				\XBRL_Log::getInstance()->valueassertion_validation( "Value assertion", "Failed to compile test expression",
					array(
						'test expression' => $this->test,
						'error' => $ex instanceof XPath2Exception ? $ex->ErrorCode : get_class( $ex ),
						'reason' => $ex->getMessage()
					)
				);

				return false;
			}

		}

		return true;
	}