{
List matchedTopics = new ArrayList();
TopicSpace topicSpace = getTopicSpace( topicSpaceSet, topicPath );
if ( topicPath.getLocalPart().indexOf( "///" ) != -1 )
{
throw new InvalidTopicExpressionException( "Topic path '" + topicPath +
"' contains an empty path component." );
}
PathTokenizer pathTokenizer = new PathTokenizer( topicPath.getLocalPart() );
List topicSetsToSearch = new ArrayList();
topicSetsToSearch.add( topicSpace );
boolean atFirstToken = true;
while ( pathTokenizer.hasMoreTokens() )
{
String pathToken = pathTokenizer.nextToken();
matchedTopics.clear();
for ( int i = 0; i < topicSetsToSearch.size(); i++ )
{
TopicSet topicSetToSearch = (TopicSet) topicSetsToSearch.get( i );
boolean recurse = pathToken.startsWith( "/" );
String name = recurse ? pathToken.substring( 1 ) : pathToken;
matchedTopics.addAll( findTopics( topicSetToSearch, name, recurse ) );
}
if ( atFirstToken && matchedTopics.isEmpty() )
{
throw new InvalidTopicExpressionException( "Topic path '" + topicPath +
"' refers to a root topic that is not defined in the referenced topic space." );
}
topicSetsToSearch.clear();
topicSetsToSearch.addAll( matchedTopics );
atFirstToken = false;