/** {@inheritDoc}
		 */
		@Override
		public void run() {
			try {
				Thread.currentThread().setName(
						Locale.getString(JanusJXTAGroup.class,
								"SERVER_THREADS_NAME", //$NON-NLS-1$
								getPeerGroup().getPeerName()));
			}
			catch(AssertionError e) {
				throw e;
			}
			catch(Throwable _) {
				//
			}
			try {
				if (this.serverPipe == null) {
					this.serverPipe = new JxtaServerPipe(
							getPeerGroup(), 
							PipeUtil.getAdvertisement(
									getPeerGroup(), 
									getPeerGroup().getPeerName(), 
									PipeService.UnicastType, 
									null));
					// lock forever
					this.serverPipe.setPipeTimeout(0);
				}

				while (true) {
					JxtaBiDiPipe bidiPipe = this.serverPipe.accept();
					if (bidiPipe != null) {
						IncommingConnectionHandler handler = new IncommingConnectionHandler();
						handler.attachBiDiPipe(bidiPipe);
					}
				}

			} catch (AssertionError ae) {
				throw ae;
			} catch (IOException e) {
				Logger.getLogger(getClass().getName()).severe(Throwables.toString(e));
			}

		}
		/**
		 * {@inheritDoc}
		 */
		@Override
		public void pipeMsgEvent(PipeMsgEvent event) {
			net.jxta.endpoint.Message message = event.getMessage();
			if (message == null) return;
			try {

				this.responseAddress = (AgentAddress) MessageUtils.getObjectFromMessage(
						message, 
						JanusJXTAGroup.MSG_NAMESPACE_SENDING, 
						JanusJXTAGroup.MSG_ELEM_REVEICER_RETURN_ADDRESS);
				synchronized (this.responseLock) {
					this.responseLock.notifyAll();
				}
			}
			catch (AssertionError ae) {
				throw ae;
			}
			catch (Exception e) {
				Logger.getLogger(getClass().getName()).severe(Throwables.toString(e));
			}
		}
		/**
		 * @param msg
		 * @param isBroadcast
		 * @return the address of the receiver agent
		 * @throws IOException
		 */
		public AgentAddress send(net.jxta.endpoint.Message msg, boolean isBroadcast) throws IOException {
			try {
				this.pipe.sendMessage(msg);

				// wait the secs if nothing comes back assume failure

				if (!isBroadcast) {
					synchronized (this.responseLock) {
						// assume failure affet 10 secs
						this.responseLock.wait(10000);
					}
				}
				return this.responseAddress;
			}
			catch (AssertionError ae) {
				throw ae;
			}
			catch (InterruptedException e) {
				Logger.getLogger(getClass().getName()).severe(Throwables.toString(e));
			}
			return null;
		}
		/** {@inheritDoc}
		 */
		@Override
		public void pipeMsgEvent(PipeMsgEvent event) {
			net.jxta.endpoint.Message message = event.getMessage();
			if (message == null || this.pipe==null) {
				return;
			}
			try {
				Message janusMessage = (Message) MessageUtils.getObjectFromMessage(
						message, 
						JanusJXTAGroup.MSG_NAMESPACE_SENDING, 
						JanusJXTAGroup.MSG_ELEM_OBJ);
				boolean isBroadcast = COMM_TYPE_BROADCAST.equals(MessageUtils.getStringFromMessage(message, MSG_NAMESPACE_SENDING, MSG_ELEM_COMM_TYPE));
				

				Address receiver = JanusJXTAGroup.this.processIncomingMessage(janusMessage, isBroadcast);
				
				if (!isBroadcast) {
					// REPLAY the receivers address
					net.jxta.endpoint.Message replay = new net.jxta.endpoint.Message();
					MessageUtils.addObjectToMessage(replay, 
							MSG_NAMESPACE_SENDING, 
							MSG_ELEM_REVEICER_RETURN_ADDRESS, 
							receiver);
					this.pipe.sendMessage(replay);
				}
				this.pipe.close();
				this.pipe.setMessageListener(null);
				this.pipe = null;
			}
			catch (AssertionError ae) {
				throw ae;
			}
			catch (Exception e) {
				Logger.getLogger(getClass().getName()).severe(Throwables.toString(e));
			}
		}