gt: 			return new RefsAndEntries(this.notify(potentialPredecessor),
context: /***************************************************************************
   *                                                                         *
   *                               NodeImpl.java                             *
   *                            -------------------                          *
   *   date                 : 16.08.2004                                     *
   *   copyright            : (C) 2004-2008 Distributed and                  *
   *                              Mobile Systems Group                       *
   *                              Lehrstuhl fuer Praktische Informatik       *
   *                              Universitaet Bamberg                       *
   *                              http://www.uni-bamberg.de/pi/              *
   *   email                : sven.kaffille@uni-bamberg.de                   *
   *   			    		karsten.loesing@uni-bamberg.de                 *
   *                                                                         *
   *                                                                         *
   ***************************************************************************/
  
  /***************************************************************************
   *                                                                         *
   *   This program is free software; you can redistribute it and/or modify  *
   *   it under the terms of the GNU General Public License as published by  *
   *   the Free Software Foundation; either version 2 of the License, or     *
   *   (at your option) any later version.                                   *
   *                                                                         *
   *   A copy of the license can be found in the license.txt file supplied   *
   *   with this software or at: http://www.gnu.org/copyleft/gpl.html        *
   *                                                                         *
   ***************************************************************************/
  package de.uniba.wiai.lspi.chord.service.impl;
  
  import static de.uniba.wiai.lspi.util.logging.Logger.LogLevel.DEBUG;
  import static de.uniba.wiai.lspi.util.logging.Logger.LogLevel.INFO;
  
  import java.util.HashSet;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.Set;
  import java.util.concurrent.Executor;
  import java.util.concurrent.locks.Lock;
  import java.util.concurrent.locks.ReentrantLock;
  
  import de.uniba.wiai.lspi.chord.com.CommunicationException;
  import de.uniba.wiai.lspi.chord.com.Endpoint;
  import de.uniba.wiai.lspi.chord.com.Entry;
  import de.uniba.wiai.lspi.chord.com.Node;
  import de.uniba.wiai.lspi.chord.com.RefsAndEntries;
  import de.uniba.wiai.lspi.chord.data.ID;
  import de.uniba.wiai.lspi.chord.data.URL;
  import de.uniba.wiai.lspi.util.logging.Logger;
  
  /**
   * Implements all operations which can be invoked remotely by other nodes.
   * 
   * @author Karsten Loesing
   * @version 1.0.5
   */
  public final class NodeImpl extends Node {
  
  	/**
  	 * Endpoint for incoming communication.
  	 */
  	private Endpoint myEndpoint = null;
  
  	/**
  	 * Reference on local node.
  	 */
  	private ChordImpl impl;
  
  	/**
  	 * Object logger.
  	 * The name of the logger is the name of this class with the nodeID appended. 
  	 * The length of the nodeID depends on the number of bytes that are displayed 
  	 * when the ID is shown in Hex-Representation. See documentation of {@link ID}. 
  	 * E.g. de.uniba.wiai.lspi.chord.service.impl.NodeImpl.FF FF FF FF if the number 
  	 * of displayed Bytes of an ID is 4. 
  	 */
  	private Logger logger;
  
  	/**
  	 * Routing table (including finger table, successor list, and predecessor
  	 * reference)
  	 */
  	private References references;
  
  	/**
  	 * Repository for locally stored entries.
  	 */
  	private Entries entries;
  
  	/**
  	 * Executor that executes insertion and removal of entries on successors of
  	 * this node.
  	 */
  	private Executor asyncExecutor;
  	
  	private Lock notifyLock; 
  
  	/**
  	 * Creates that part of the local node which answers remote requests by
  	 * other nodes. Sole constructor, is invoked by ChordImpl only.
  	 * 
  	 * @param impl
  	 *            Reference on ChordImpl instance which created this object.
  	 * @param nodeID
  	 *            This node's Chord ID.
  	 * @param nodeURL
  	 *            URL, on which this node accepts connections.
  	 * @param references
  	 *            Routing table of this node.
  	 * @param entries
  	 *            Repository for entries of this node.
  	 * @throws IllegalArgumentException
  	 *             If any of the parameter has value <code>null</code>.
  	 */
  	NodeImpl(ChordImpl impl, ID nodeID, URL nodeURL, References references,
  			Entries entries) {
  
  		if (impl == null || nodeID == null || nodeURL == null
  				|| references == null || entries == null) {
  			throw new IllegalArgumentException(
  					"Parameters of the constructor may not have a null value!");
  		}
  
  		this.logger = Logger.getLogger(NodeImpl.class.getName() + "." + nodeID.toString());
  
  		this.impl = impl;
  		this.asyncExecutor = impl.getAsyncExecutor();
  		this.nodeID = nodeID;
  		this.nodeURL = nodeURL;
  		this.references = references;
  		this.entries = entries;
  		this.notifyLock = new ReentrantLock(true); 
  		
  		// create endpoint for incoming connections
  		this.myEndpoint = Endpoint.createEndpoint(this, nodeURL);
  		this.myEndpoint.listen();
  	}
  
  	/**
  	 * Makes this endpoint accept entries by other nodes. Is invoked by
  	 * ChordImpl only.
  	 */
  	final void acceptEntries() {
  		this.myEndpoint.acceptEntries();
  	}
  
  	/**
  	 * {@inheritDoc}
  	 */
  	@Override
  	public final void disconnect() {
  		this.myEndpoint.disconnect();
  	}
  
  	/**
  	 * {@inheritDoc}
  	 */
  	@Override
  	public final Node findSuccessor(ID key) {
  		return this.impl.findSuccessor(key);
  	}
  
  	/**
  	 * {@inheritDoc}
  	 */
  	@Override
  	public final List<Node> notify(Node potentialPredecessor) {
  		/*
  		 * Mutual exclusion between notify and notifyAndCopyEntries. 17.03.2008. sven.
  		 */
  		this.notifyLock.lock(); 
  		try {
  			// the result will contain the list of successors as well as the
  			// predecessor of this node
  			List<Node> result = new LinkedList<Node>();
  
  			// add reference on predecessor as well as on successors to result
  			if (this.references.getPredecessor() != null) {
  				result.add(this.references.getPredecessor());
  			} else {
  				result.add(potentialPredecessor); 
  			}
  			result.addAll(this.references.getSuccessors());
  
  //			 add potential predecessor to successor list and finger table and
  			// set
  			// it as predecessor if no better predecessor is available
  			this.references.addReferenceAsPredecessor(potentialPredecessor);			
  			return result;
  		} finally {
  			this.notifyLock.unlock(); 
  		}
  	}
  
  	/**
  	 * {@inheritDoc}
  	 */
  	@Override
  	public final RefsAndEntries notifyAndCopyEntries(Node potentialPredecessor)
  			throws CommunicationException {
  		/*
  		 * Mutual exclusion between notify and notifyAndCopyEntries. 17.03.2008. sven.
  		 */
  		this.notifyLock.lock(); 
  		try {
  			// copy all entries which lie between the local node ID and the ID
  			// of
  			// the potential predecessor, including those equal to potential
  			// predecessor
  			Set<Entry> copiedEntries = this.entries.getEntriesInInterval(
  					this.nodeID, potentialPredecessor.getNodeID());
  
  