public function processSchema( $xsd, $includeElements = false )
	{
		libxml_use_internal_errors();

		$xml = @simplexml_load_file( $xsd );
		if ( ! $xml )
		{
			return false;
		}

		$activeSchemaPrefix = null;

		$prefix = null;
		$targetNamespace = (string) $xml->attributes()->targetNamespace;
		foreach ( $xml->getDocNamespaces() as $namespacePrefix => $namespace )
		{
			if ( ! empty( $namespacePrefix ) && $namespace == SCHEMA_NAMESPACE )
			{
				$activeSchemaPrefix = $namespacePrefix;
			}

			$xml->registerXPathNamespace( $namespacePrefix, $namespace );
			if ( $namespace != $targetNamespace ) continue;
			$prefix = $namespacePrefix;
		}
		$xml->registerXPathNamespace( SCHEMA_PREFIX, SCHEMA_NAMESPACE );

		if ( ! $prefix )
		{
			// If there is no prefix generate a random one
			$prefix = substr( str_shuffle( "abcdefghijklmnopqrstuvwxyz" ), 0, 8 );
		}

		$xpath = new \DOMXPath( dom_import_simplexml( $xml )->ownerDocument );
		$xpath->registerNamespace( SCHEMA_PREFIX, SCHEMA_NAMESPACE );
		$imports = $xpath->query( "/xs:schema/xs:import" );

		foreach ( $imports as $import )
		{
			$nextNamespace = (string) $import->getAttribute( 'namespace' );

			$schemaLocation = (string) $import->getAttribute( 'schemaLocation' );
			$nextXSD = SchemaTypes::resolve_path( $xsd, $schemaLocation );

			$this->processSchema( $nextXSD, $includeElements );
		}

		if ( in_array( $targetNamespace, $this->processedSchemas ) ) return true;

		$this->processedSchemas[ $prefix ] = $targetNamespace;
		$this->activeSchemaPrefix = $activeSchemaPrefix;

		foreach ( $xml->children( SCHEMA_NAMESPACE ) as $nodeKey => $node )
		{
			$this->processNode( $node, $nodeKey, $prefix, $includeElements );
		}

		return true;
	}