private void start(String props, String cluster_name,
                       long rpc_timeout, long caching_time, boolean migrate_data, boolean use_l1_cache,
                       int l1_max_entries, long l1_reaping_interval,
                       int l2_max_entries, long l2_reaping_interval) throws Exception {
        MBeanServer server=ManagementFactory.getPlatformMBeanServer();

        cache=new ReplCache<>(props, cluster_name);
        cache.setCallTimeout(rpc_timeout);
        cache.setCachingTime(caching_time);
        cache.setMigrateData(migrate_data);
        JmxConfigurator.register(cache, server, BASENAME + ":name=cache");
        JmxConfigurator.register(cache.getL2Cache(), server, BASENAME + ":name=l2-cache");

        if(use_l1_cache) {
            Cache<String,String> l1_cache=new Cache<>();
            cache.setL1Cache(l1_cache);
            if(l1_reaping_interval > 0)
                l1_cache.enableReaping(l1_reaping_interval);
            if(l1_max_entries > 0)
                l1_cache.setMaxNumberOfEntries(l1_max_entries);
            JmxConfigurator.register(cache.getL1Cache(), server, BASENAME + ":name=l1-cache");
        }

        if(l2_max_entries > 0 || l2_reaping_interval > 0) {
            Cache<String, ReplCache.Value<String>> l2_cache=cache.getL2Cache();
            if(l2_max_entries > 0)
                l2_cache.setMaxNumberOfEntries(l2_max_entries);
            if(l2_reaping_interval > 0)
                l2_cache.enableReaping(l2_reaping_interval);
        }


        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                cache.stop();
            }
        });

        cache.start();

        model=new MyTableModel<String,String>();
        model.setMap(cache.getL2Cache().getInternalMap());
        cache.addChangeListener(model);

        frame=new JFrame("ReplCacheDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));

        table=new MyTable(model);
        table.setPreferredScrollableViewportSize(new Dimension(500, 200));
        // table.setFillsViewportHeight(true); // JDK 6 specific
        table.setShowGrid(false);
        table.setFont(table.getFont().deriveFont(Font.BOLD));
        add(new JScrollPane(table));

        JPanel key=new JPanel(new FlowLayout(FlowLayout.LEFT));
        key.add(new JLabel("Key  "));
        key.add(key_field);
        add(key);

        JPanel value=new JPanel(new FlowLayout(FlowLayout.LEFT));
        value.add(new JLabel("Value"));
        value.add(value_field);
        add(value);

        JPanel repl_count=new JPanel(new FlowLayout(FlowLayout.LEFT));
        repl_count.add(new JLabel("Replication count"));
        repl_count.add(repl_count_field);
        add(repl_count);

        JPanel timeout=new JPanel(new FlowLayout(FlowLayout.LEFT));
        timeout.add(new JLabel("Timeout"));
        timeout.add(timeout_field);
        add(timeout);

        JPanel buttons=new JPanel();
        JButton put_button=createButton("Put");
        buttons.add(createButton("Put"));
        buttons.add(createButton("Remove"));
        buttons.add(createButton("Clear"));
        buttons.add(createButton("Rebalance"));
        buttons.add(createButton("Exit"));
        buttons.add(num_elements);
        add(buttons);
        setOpaque(true);

        root_pane.addTab("Data", this);
        JPanel perf_panel=new JPanel();
        perf_panel.setLayout(new BoxLayout(perf_panel, BoxLayout.Y_AXIS));
        perf_panel.setOpaque(true);
        root_pane.addTab("Perf test", perf_panel);

        perf_panel.add(status);
        status.setForeground(Color.BLUE);

        JPanel prefix=new JPanel(new FlowLayout(FlowLayout.LEFT));
        prefix.add(new JLabel("Key prefix"));
        prefix.add(perf_key_prefix);
        perf_panel.add(prefix);

        JPanel keys=new JPanel(new FlowLayout(FlowLayout.LEFT));
        keys.add(new JLabel("Number of keys to insert"));
        keys.add(perf_num_keys);
        perf_panel.add(keys);

        JPanel size=new JPanel(new FlowLayout(FlowLayout.LEFT));
        size.add(new JLabel("Size of each key (bytes)"));
        size.add(perf_size); size.add(new JLabel("    (ignored for now)"));
        perf_panel.add(size);

        JPanel perf_repl_count=new JPanel(new FlowLayout(FlowLayout.LEFT));
        perf_repl_count.add(new JLabel("Replication count"));
        perf_repl_count.add(perf_repl_count_field);
        perf_panel.add(perf_repl_count);

        JPanel perf_timeout=new JPanel(new FlowLayout(FlowLayout.LEFT));
        perf_timeout.add(new JLabel("Timeout"));
        perf_timeout.add(perf_timeout_field);
        perf_panel.add(perf_timeout);

        JPanel perf_buttons=new JPanel(new FlowLayout(FlowLayout.LEFT));
        perf_buttons.add(createButton("Start"));
        perf_buttons.add(createButton("Stop"));
        perf_buttons.add(createButton("Reset"));
        perf_buttons.add(createButton("Exit"));
        perf_panel.add(perf_buttons);

        frame.setContentPane(root_pane);
        frame.pack();
        frame.getRootPane().setDefaultButton(put_button);
        frame.setVisible(true);
        setTitle("ReplCacheDemo");

        cache.addMembershipListener(new MembershipListener() {
            public void viewAccepted(View new_view) {
                setTitle("ReplCacheDemo");
            }

            public void suspect(Address suspected_mbr) {
            }

            public void block() {
            }

            public void unblock() {
            }
        });
    }