/*
 * This file is part of Bitsquare.
 *
 * Bitsquare is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or (at
 * your option) any later version.
 *
 * Bitsquare is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
 */

package io.bitsquare.app.cli;

import io.bitsquare.network.Node;

import net.tomp2p.dht.PeerBuilderDHT;
import net.tomp2p.dht.PeerDHT;
import net.tomp2p.nat.PeerBuilderNAT;
import net.tomp2p.p2p.Peer;
import net.tomp2p.p2p.PeerBuilder;
import net.tomp2p.peers.Number160;
import net.tomp2p.peers.PeerAddress;
import net.tomp2p.replication.IndirectReplication;
import net.tomp2p.rpc.ObjectDataReply;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.core.env.Environment;

public class BootstrapNode {
    private static final Logger log = LoggerFactory.getLogger(BootstrapNode.class);

    private static Peer peer = null;
    private static boolean running = true;

    private final Environment env;

    public BootstrapNode(Environment env) {
        this.env = env;
    }

    public void start() {
        String name = env.getRequiredProperty(Node.NAME_KEY);
        int port = env.getProperty(Node.PORT_KEY, Integer.class, Node.DEFAULT_PORT);

        try {
            Number160 peerId = Number160.createHash(name);
            peer = new PeerBuilder(peerId).ports(port).start();
            peer.objectDataReply(new ObjectDataReply() {
                @Override
                public Object reply(PeerAddress sender, Object request) throws Exception {
                    log.trace("received request: ", request.toString());
                    return "pong";
                }
            });

            PeerDHT peerDHT = new PeerBuilderDHT(peer).start();
            new PeerBuilderNAT(peer).start();
            new IndirectReplication(peerDHT).start();

            log.debug("Bootstrap node started with name " + name + " and port " + port);
            new Thread(new Runnable() {
                @Override
                public void run() {
                    while (running) {
                        for (PeerAddress pa : peer.peerBean().peerMap().all()) {
                            log.debug("peer online:" + pa);
                        }
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            return;
                        }
                    }
                }
            }).start();

        } catch (Exception e) {
            if (peer != null)
                peer.shutdown().awaitUninterruptibly();
        }
    }
}

@@ -1025,78 +1025,125 @@
 p2p.
-replication.IndirectReplication;%0Aimport net.tomp2p.rpc.ObjectDataReply
+peers.PeerMapChangeListener;%0Aimport net.tomp2p.peers.PeerStatistic;%0Aimport net.tomp2p.replication.IndirectReplication
 ;%0A%0Ai
@@ -1903,120 +1903,16 @@
 ply(
-new ObjectDataReply() %7B%0A                @Override%0A                public Object reply(PeerAddress 
+(
 sender,
- Object
  req
@@ -1921,31 +1921,13 @@
 st) 
-throws Exception %7B%0A    
+-%3E %7B%0A
     
@@ -1968,17 +1968,18 @@
 quest: %22
-,
+ +
  request
@@ -1992,20 +1992,16 @@
 ing());%0A
-    
         
@@ -2023,34 +2023,16 @@
 %22pong%22;%0A
-                %7D%0A
         
@@ -2221,191 +2221,771 @@
     
-log.debug(%22Bootstrap node started with name %22 + name + %22 and port %22 + port);%0A            new Thread(new Runnable() %7B%0A                @Override%0A                public void run() %7B%0A    
+peer.peerBean().peerMap().addPeerMapChangeListener(new PeerMapChangeListener() %7B%0A                @Override%0A                public void peerInserted(PeerAddress peerAddress, boolean verified) %7B%0A                    log.debug(%22peerInserted: %22 + peerAddress);%0A                %7D%0A%0A                @Override%0A                public void peerRemoved(PeerAddress peerAddress, PeerStatistic storedPeerAddress) %7B%0A                    log.debug(%22peerRemoved: %22 + peerAddress);%0A                %7D%0A%0A                @Override%0A                public void peerUpdated(PeerAddress peerAddress, PeerStatistic storedPeerAddress) %7B%0A                %7D%0A            %7D);%0A%0A            log.debug(%22Bootstrap node started with name %22 + name + %22 and port %22 + port);%0A            new Thread(() -%3E %7B%0A
     
@@ -3010,28 +3010,24 @@
 (running) %7B%0A
-    
             
@@ -3052,17 +3052,26 @@
 ddress p
-a
+eerAddress
  : peer.
@@ -3116,36 +3116,32 @@
                 
-    
 log.debug(%22peer 
@@ -3135,17 +3135,17 @@
 .debug(%22
-p
+P
 eer onli
@@ -3151,14 +3151,24 @@
 ine:
+ 
 %22 + p
-a
+eerAddress
 );%0A 
@@ -3182,33 +3182,26 @@
             
-    %7D%0A   
+%7D%0A
             
@@ -3204,35 +3204,30 @@
             
- 
 try %7B%0A
-    
             
@@ -3255,19 +3255,16 @@
 eep(
-2
+6
 000
+0
 );%0A
-    
     
@@ -3342,20 +3342,16 @@
     
-  
-  
 return;%0A
     
@@ -3350,34 +3350,8 @@
 rn;%0A
-                        %7D%0A
     

Add logs at peer insert and remove