private function compareConcepts( $expectedNav, $generatedNav, $expectedContexts, $generatedContexts, $expectedUnits, $generatedUnits, $expectedConceptNavIsTuple, $generatedNavIsTuple )
	{
		// Compare the names
		if ( $expectedNav->getLocalName() != $generatedNav->getLocalName() ||
			 $expectedNav->getNamespaceURI() != $generatedNav->getNamespaceURI() )
		{
			$this->comparisonError = "The concept names and/or namespaces do not match for concept line numbers {$expectedNav->getLineNo()} and {$generatedNav->getLineNo()}";
			return false;
		}

		if ( $expectedConceptNavIsTuple != $generatedNavIsTuple )
		{
			return false;
		}

		if ( $expectedConceptNavIsTuple )
		{
			return true;
		}

		// Make sure the elements have the same parent
		$expectedNavParent = $expectedNav->CloneInstance();
		$generatedNavParent = $generatedNav->CloneInstance();

		$expectedNavHasParent = $expectedNavParent->MoveToParent();
		$generatedNavHasParent = $generatedNavParent->MoveToParent();

		if (  $expectedNavHasParent != $generatedNavHasParent )
		{
			return false;
		}

		if ( $expectedNavParent->getLocalName() != $generatedNavParent->getLocalName() || $expectedNavParent->getNamespaceURI() != $generatedNavParent->getNamespaceURI() )
		{
			return false;
		}

		// Compare the value if it is a simple value
		$expectedHasChildren = $expectedNav->CloneInstance()->MoveToChild( XPathNodeType::Element );
		$generatedHasChildren = $generatedNav->CloneInstance()->MoveToChild( XPathNodeType::Element );

		if ( $expectedHasChildren != $generatedHasChildren )
		{
			$this->comparisonError = "There is a mis-match between the number of nested elements in expected concept {$expectedNav->getLineNo()} ({$expectedNav->getName()})";
			return false;
		}

		if ( ! $generatedHasChildren )
		{
			$expectedValue = trim( $expectedNav->getValue() );
			$generatedValue = trim( $generatedNav->getValue() );
			if ( $expectedValue != $generatedValue )
			{
				$this->comparisonError = "The values in expected concept {$expectedNav->getLineNo()} ({$expectedNav->getName()}) do not match";
				return false;
			}
		}

		// Compare the attributes
		if ( ! $this->compareAttributes( $expectedNav, $generatedNav, $expectedContexts, $generatedContexts, $expectedUnits, $generatedUnits ) )
		{
			// Any error will be reported by the sub-function
			return false;
		}

		// BMS 2018-03-18 Don't want to do this because the child elements may be in a different order but still equivalent (just not exactly the same).
		// // Compare any nested elements (tuples)
		// if ( $generatedHasChildren )
		// {
		// 	$expectedChildNav = $expectedNav->CloneInstance();
		// 	$result1 = $expectedChildNav->MoveToChild( XPathNodeType::Element );
        //
		// 	$generatedChildNav = $expectedNav->CloneInstance();
		// 	$result2 = $generatedChildNav->MoveToChild( XPathNodeType::Element );
        //
		// 	do
		// 	{
		// 		if ( ! $this->compareConcepts(
		// 				$expectedChildNav,
		// 				$generatedChildNav,
		// 				$expectedContexts,
		// 				$generatedContexts,
		// 				$expectedUnits,
		// 				$generatedUnits
		// 			)
		// 		)
		// 		{
		// 			// Any error will be reported by the sub-function
		// 			return false;
		// 		}
        //
		// 		$result1 = $expectedChildNav->MoveToNext( XPathNodeType::Element );
		// 		$result2 = $generatedChildNav->MoveToNext( XPathNodeType::Element );
		// 	}
		// 	while( $result1 && $result2 );
        //
		// }

		return true;
	}