public void queryAllNodes( float timeout, ActionListener doneAction )
	{
		setFireAllNodes( true );
		setAutoRegister( true );
	
		final Set			setNodes		= new HashSet();
		final NodeListener	nl;
		final Timer			stopQueryTimer;

		stopQueryTimer = new Timer( (int) (timeout * 1000), null );
		
		nl = new NodeListener() {
			public void nodeAction( NodeEvent e )
			{
				if( e.getID() != NodeEvent.INFO ) return;

				final Node		n			= e.getNode();
				final List		nextNodes;
				
				if( setNodes.add( n )) {
					register( n );
					nextNodes = new ArrayList( 2 );
					if( e.getHeadNodeID() != -1 ) nextNodes.add( new Integer( e.getHeadNodeID() ));
					if( e.getSuccNodeID() != -1 ) nextNodes.add( new Integer( e.getSuccNodeID() ));
					if( !nextNodes.isEmpty() ) {
						try {
							server.sendMsg( new OSCMessage( "/n_query", nextNodes.toArray() ));
						}
						catch( IOException e1 ) {
							e1.printStackTrace();
						}
					}
				}

				stopQueryTimer.restart();
			}
		};

		stopQueryTimer.addActionListener( new ActionListener() {
			public void actionPerformed( ActionEvent e )
			{
				removeListener( nl );
			}
		});
		if( doneAction != null ) stopQueryTimer.addActionListener( doneAction );
		stopQueryTimer.setRepeats( false );
		stopQueryTimer.restart();
		
		addListener( nl );
		try {
			server.sendMsg( server.getDefaultGroup().queryMsg() );
		}
		catch( IOException e1 ) {
			e1.printStackTrace();
		}
	}