@SuppressWarnings({"serial"})
	public static VisualizationViewer<Integer, Integer> setupJungViewer(final DelegateTree<Integer, Integer> tree, final LineageDisplayConfig config) {
		Layout<Integer, Integer> treeLayout = new TreeLayout<Integer, Integer>((Forest<Integer, Integer>) tree, 90, 130);
		VisualizationViewer<Integer, Integer> treeView = new VisualizationViewer<Integer, Integer>(treeLayout);
		DefaultModalGraphMouse<Integer, Integer> graphMouse = new DefaultModalGraphMouse<Integer, Integer>();
		graphMouse.setMode(ModalGraphMouse.Mode.PICKING);
		treeView.setGraphMouse(graphMouse);
		treeView.setBackground(Color.WHITE);
		treeView.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createRaisedBevelBorder(), BorderFactory.createLoweredBevelBorder()));
		ScalingControl scaler = new CrossoverScalingControl();
		scaler.scale(treeView, 1 / 1.5f, treeView.getLocation());
		
		// ---- vertices -----
		treeView.getRenderer().getVertexLabelRenderer().setPosition(Position.S);
		treeView.getRenderContext().setVertexLabelRenderer(new DefaultVertexLabelRenderer(Color.BLACK) {
            @Override
            public <V> Component getVertexLabelRendererComponent(
                JComponent vv, Object value, Font font, 
                boolean isSelected, V vertex) { // color
                	super.getVertexLabelRendererComponent(vv, value, font, isSelected, vertex);
                	if(!isSelected) {
                		setForeground(config.getNodeLabelColor((Integer) vertex));
                	}
                	return this;
        }}); 
		treeView.getRenderer().setVertexRenderer(new BasicVertexRenderer<Integer, Integer>() {
			@Override
			protected void paintIconForVertex(RenderContext<Integer,Integer> rc, Integer v, Layout<Integer,Integer> layout) { 
		        GraphicsDecorator g = rc.getGraphicsContext(); 
		        boolean vertexHit = true; 
		        Shape shape = rc.getVertexShapeTransformer().transform(v); 
		        Point2D p = layout.transform(v); 
		        p = rc.getMultiLayerTransformer().transform(Layer.LAYOUT, p); 
		        float x = (float)p.getX(); 
		        float y = (float)p.getY(); 
		        AffineTransform xform = AffineTransform.getTranslateInstance(x,y); 
		        shape = xform.createTransformedShape(shape); 
		        vertexHit = vertexHit(rc, shape);  
		        if (vertexHit) { 
		        	if(rc.getVertexIconTransformer() != null) { 
		        		Icon icon = rc.getVertexIconTransformer().transform(v); 
		        		if(icon != null) { 
		        			paintShapeForVertex(rc, v, shape);
		        			g.draw(icon, rc.getScreenDevice(), shape, (int)x, (int)y); 
		        		} else { 
		        			paintShapeForVertex(rc, v, shape); 
		        		} 
		        	} else { 
		        		paintShapeForVertex(rc, v, shape); 
		        	} 
		        } 
		    } 
		});
		treeView.getRenderContext().setVertexFontTransformer(new Transformer<Integer, Font>() {
			public Font transform(Integer num) { // font
				return config.getNodeFont(num);
		}});	
		treeView.getRenderContext().setVertexLabelTransformer(new Transformer<Integer, String>(){
			public String transform(Integer num) { // label
				return config.getExternalNodeLabel(num);
		 }});
		treeView.getRenderContext().setVertexShapeTransformer(new Transformer<Integer, Shape>() {
			public Shape transform(Integer num) { // shape
				return config.getNodeShape(num);
		} });
		final PickedState<Integer> pickedState = treeView.getPickedVertexState();
		treeView.getRenderContext().setVertexIconTransformer(new Transformer<Integer, Icon> () {
			public Icon transform(final Integer num) {
				return config.getNodeIcon(num);
		}});
		treeView.getRenderContext().setVertexFillPaintTransformer(new Transformer<Integer, Paint>() {
			public Paint transform(Integer s) { // colors
				if(pickedState.isPicked(s)) {
					return LineageDisplayConfig.ColorPalette.SELECTED_NODE_COLOR;
				}
				return config.getNodeFillColor(s);
			}
			
		});
		treeView.getRenderContext().setVertexDrawPaintTransformer(new Transformer<Integer, Paint>() {
			public Paint transform(Integer s) {
				return config.getNodeBorderColor(s);
			}
		});
		treeView.getRenderContext().setVertexStrokeTransformer(new Transformer<Integer, Stroke>() {
			public Stroke transform(Integer s) {
				return new BasicStroke(3.0f);
			}
		});
		
		// ----- edges -----
		if(config.beautify) {
			treeView.getRenderContext().setEdgeShapeTransformer(new EdgeShape.CubicCurve<Integer, Integer>());
		} else {
			treeView.getRenderContext().setEdgeShapeTransformer(new EdgeShape.QuadCurve<Integer, Integer>());
		}
		//treeView.getRenderContext().setEdgeShapeTransformer(new EdgeShape.Line<Integer, Integer>());
		treeView.getRenderContext().getEdgeLabelRenderer().setRotateEdgeLabels(false);
		treeView.getRenderContext().setLabelOffset(20);
		treeView.getRenderContext().setEdgeLabelClosenessTransformer(new ConstantDirectionalEdgeValueTransformer<Integer, Integer>(0.5d, 0.5d));	
		treeView.getRenderContext().setArrowFillPaintTransformer(treeView.getRenderContext().getEdgeDrawPaintTransformer());
		treeView.getRenderContext().setArrowDrawPaintTransformer(treeView.getRenderContext().getEdgeDrawPaintTransformer());
		treeView.getRenderContext().setEdgeDrawPaintTransformer(new Transformer<Integer, Paint>() {
			public Paint transform(Integer s) { // color
				return config.getEdgeColor(tree.getSource(s), tree.getDest(s));
			}
		});
		treeView.getRenderContext().setEdgeStrokeTransformer(new Transformer<Integer, Stroke>() {
			public Stroke transform(Integer s) { // edge width
				if(config.beautify) {
					return new BasicStroke(14.0f);
				} else {
					return new BasicStroke(2.0f);
				}
			}
		});
		treeView.getRenderContext().setEdgeFontTransformer(new Transformer<Integer, Font>() {
			public Font transform(Integer num) { // font
				return config.getEdgeFont();
		}});
		treeView.getRenderContext().setEdgeLabelTransformer(new Transformer<Integer, String>(){
			public String transform(Integer s) { // text
				return config.getEdgeLabel(tree.getSource(s), tree.getDest(s));
		 }});
		return treeView;
	}