]> gerrit.simantics Code Review - simantics/interop.git/blobdiff - org.simantics.interop/src/org/simantics/interop/test/GraphComparatorViewer.java
Handle asserted property statements
[simantics/interop.git] / org.simantics.interop / src / org / simantics / interop / test / GraphComparatorViewer.java
index 24e24ad0159c9bbde0461c382e807f43eafcc3b7..7d6a838211793895c99d90cbb5eddd61acf71a94 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     Foster Wheeler Energia Oy - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.interop.test;\r
-\r
-import java.io.File;\r
-import java.io.FileNotFoundException;\r
-import java.io.FileReader;\r
-import java.io.IOException;\r
-import java.io.PrintStream;\r
-import java.io.Serializable;\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.HashMap;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Stack;\r
-\r
-import javax.xml.parsers.SAXParser;\r
-import javax.xml.parsers.SAXParserFactory;\r
-\r
-import org.eclipse.jface.action.Action;\r
-import org.eclipse.jface.action.IMenuListener;\r
-import org.eclipse.jface.action.IMenuManager;\r
-import org.eclipse.jface.action.MenuManager;\r
-import org.eclipse.jface.dialogs.Dialog;\r
-import org.eclipse.jface.dialogs.IDialogConstants;\r
-import org.eclipse.jface.dialogs.MessageDialog;\r
-import org.eclipse.jface.layout.GridDataFactory;\r
-import org.eclipse.jface.viewers.IStructuredContentProvider;\r
-import org.eclipse.jface.viewers.IStructuredSelection;\r
-import org.eclipse.jface.viewers.LabelProvider;\r
-import org.eclipse.jface.viewers.ListViewer;\r
-import org.eclipse.jface.viewers.Viewer;\r
-import org.eclipse.jface.window.IShellProvider;\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.dnd.DND;\r
-import org.eclipse.swt.dnd.DropTarget;\r
-import org.eclipse.swt.dnd.DropTargetAdapter;\r
-import org.eclipse.swt.dnd.DropTargetEvent;\r
-import org.eclipse.swt.dnd.TextTransfer;\r
-import org.eclipse.swt.dnd.Transfer;\r
-import org.eclipse.swt.events.SelectionAdapter;\r
-import org.eclipse.swt.events.SelectionEvent;\r
-import org.eclipse.swt.layout.FillLayout;\r
-import org.eclipse.swt.layout.GridData;\r
-import org.eclipse.swt.layout.GridLayout;\r
-import org.eclipse.swt.widgets.Button;\r
-import org.eclipse.swt.widgets.Composite;\r
-import org.eclipse.swt.widgets.Control;\r
-import org.eclipse.swt.widgets.Display;\r
-import org.eclipse.swt.widgets.FileDialog;\r
-import org.eclipse.swt.widgets.Group;\r
-import org.eclipse.swt.widgets.Label;\r
-import org.eclipse.swt.widgets.Shell;\r
-import org.eclipse.swt.widgets.Text;\r
-import org.eclipse.ui.part.ViewPart;\r
-import org.simantics.Simantics;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.Session;\r
-import org.simantics.db.Statement;\r
-import org.simantics.db.common.ResourceArray;\r
-import org.simantics.db.common.request.ReadRequest;\r
-import org.simantics.db.common.utils.NameUtils;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.exception.ServiceException;\r
-import org.simantics.db.exception.ValidationException;\r
-import org.simantics.db.request.Read;\r
-import org.simantics.db.service.SerialisationSupport;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.ui.dnd.LocalObjectTransfer;\r
-import org.simantics.ui.dnd.ResourceReferenceTransfer;\r
-import org.simantics.ui.dnd.ResourceTransferUtils;\r
-import org.simantics.ui.utils.ResourceAdaptionUtils;\r
-import org.simantics.utils.datastructures.BijectionMap;\r
-import org.simantics.utils.datastructures.Pair;\r
-import org.simantics.utils.ui.ExceptionUtils;\r
-import org.xml.sax.Attributes;\r
-import org.xml.sax.InputSource;\r
-import org.xml.sax.SAXException;\r
-import org.xml.sax.XMLReader;\r
-import org.xml.sax.helpers.DefaultHandler;\r
-\r
-/**\r
- * Simple multiline text viewer for seeing differences in two subgraphs. \r
- * \r
- * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
- *\r
- */\r
-public class GraphComparatorViewer extends ViewPart{\r
-       \r
-       private Session session;\r
-\r
-       private Composite composite;\r
-       \r
-       private Label resourceText1;\r
-       private Label resourceText2;\r
-       \r
-       private Text text1;\r
-       private Text text2;\r
-       \r
-       \r
-       private List<Resource> traversed = new ArrayList<Resource>();\r
-       private List<Resource> tested = new ArrayList<Resource>();\r
-       private List<Resource> strong = new ArrayList<Resource>();\r
-       private List<Resource> nonTraversed = new ArrayList<Resource>();\r
-       private List<Resource> nonTested = new ArrayList<Resource>();\r
-\r
-       \r
-       @Override\r
-       public void createPartControl(Composite parent) {\r
-               composite = new Composite(parent, SWT.NONE);\r
-               composite.setLayout(new GridLayout(2, false));\r
-               \r
-               session = Simantics.getSession();\r
-               \r
-               Composite topComposite = new Composite(composite, SWT.BORDER);\r
-               topComposite.setLayout(new GridLayout(3, false));\r
-               text1 = new Text(composite, SWT.MULTI|SWT.V_SCROLL);\r
-               text2 = new Text(composite, SWT.MULTI|SWT.V_SCROLL);\r
-               \r
-               GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP).grab(true, false).span(2, 1).applyTo(topComposite);\r
-               GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(text1);\r
-               GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(text2);\r
-               \r
-               resourceText1 = createDropLabel(topComposite);\r
-               resourceText2 = createDropLabel(topComposite);\r
-               \r
-               Button button = new Button(topComposite, SWT.PUSH);\r
-               button.setText("Compare");\r
-               button.addSelectionListener(new SelectionAdapter() {\r
-                       @Override\r
-                       public void widgetSelected(SelectionEvent e) {\r
-                               compare();\r
-                       }\r
-               });\r
-               \r
-               defaultConf();\r
-               \r
-               getViewSite().getActionBars().getToolBarManager().add(new Action("Config") {\r
-                       @Override\r
-                       public void run() {\r
-                               ConfigurationDialog dialog = new ConfigurationDialog(getSite().getShell());\r
-                               dialog.open();\r
-                       }\r
-               });\r
-               \r
-       }\r
-       \r
-       private void defaultConf() {\r
-               traversed.clear();\r
-               tested.clear();\r
-               strong.clear();\r
-               nonTested.clear();\r
-               nonTraversed.clear();\r
-               try {\r
-               session.syncRequest(new ReadRequest() {\r
-                       @Override\r
-                       public void run(ReadGraph graph) throws DatabaseException {\r
-                               Layer0 l0 = Layer0.getInstance(graph);\r
-                               traversed.add(l0.ConsistsOf);\r
-                               tested.add(l0.IsWeaklyRelatedTo);\r
-                               nonTraversed.add(l0.InstanceOf);\r
-                       }\r
-               });\r
-               } catch (Exception e) {\r
-                       ExceptionUtils.logAndShowError(e);\r
-               }\r
-       }\r
-       \r
-       private void compare() {\r
-               text1.setText("");\r
-               text2.setText("");\r
-               final Resource r1 = (Resource)resourceText1.getData();\r
-               final Resource r2 = (Resource)resourceText2.getData();\r
-               if (r1 == null || r2 == null) {\r
-                       if (r1 == null)\r
-                               text1.setText("Missing input!");\r
-                       if (r2 == null)\r
-                               text2.setText("Missing input!");\r
-                       return; \r
-               }\r
-               \r
-               session.asyncRequest(new ReadRequest() {\r
-                       \r
-                       @Override\r
-                       public void run(final ReadGraph graph) throws DatabaseException {\r
-                               GraphComparator comparator = new GraphComparator(r1,r2);\r
-                               \r
-                               comparator.addTested(tested);\r
-                               comparator.addTraversed(traversed);\r
-                               comparator.addNonTested(nonTested);\r
-                               comparator.addNonTraversed(nonTraversed);\r
-                               comparator.addStrong(strong);\r
-                               \r
-                               comparator.test(graph);\r
-                               BijectionMap<Statement, Statement> map = comparator.getComparableStatements();\r
-                               Map<Statement, Integer> indices = new HashMap<Statement, Integer>();\r
-                               final StringBuilder sb1 = new StringBuilder();\r
-                               final StringBuilder sb2 = new StringBuilder();\r
-                               int index = 0;\r
-                               \r
-                               GraphChanges changes = comparator.getChanges();\r
-                               \r
-                               for (Pair<Statement,Statement> mod : changes.getModifications()) {\r
-                                       {\r
-                                               String sub;\r
-                                               try {\r
-                                                       Statement s = mod.first;\r
-                                                       sub = NameUtils.getSafeName(graph, s.getSubject());\r
-                                                       String pre = NameUtils.getSafeName(graph, s.getPredicate());\r
-                                                       String obj = NameUtils.getSafeName(graph, s.getObject());\r
-                                                       if (map.containsLeft(s)) {\r
-                                                               index++;\r
-                                                               indices.put(s, index);\r
-                                                               sb1.append("["+index + "] ");\r
-                                                       }\r
-                                                       sb1.append(sub + " - " + pre + " - " + obj);\r
-                                                       sb1.append(" ["+s.getSubject().getResourceId() + " " + s.getPredicate().getResourceId() + " " + s.getObject().getResourceId()+"]");\r
-                                                       sb1.append("\n");\r
-                                               } catch (ValidationException e) {\r
-                                                       e.printStackTrace();\r
-                                               } catch (ServiceException e) {\r
-                                                       e.printStackTrace();\r
-                                               }\r
-                                       }\r
-                                       {\r
-                                               String sub;\r
-                                               try {\r
-                                                       Statement s = mod.second;\r
-                                                       sub = NameUtils.getSafeName(graph, s.getSubject());\r
-                                                       String pre = NameUtils.getSafeName(graph, s.getPredicate());\r
-                                                       String obj = NameUtils.getSafeName(graph, s.getObject());\r
-                                                       if (map.containsRight(s)) {\r
-                                                               index = indices.get(map.getLeft(s));\r
-                                                               sb2.append("["+index + "] ");\r
-                                                       }\r
-                                                       sb2.append(sub + " - " + pre + " - " + obj);\r
-                                                       sb2.append(" ["+s.getSubject().getResourceId() + " " + s.getPredicate().getResourceId() + " " + s.getObject().getResourceId()+"]");\r
-                                                       sb2.append("\n");\r
-                                               } catch (ValidationException e) {\r
-                                                       e.printStackTrace();\r
-                                               } catch (ServiceException e) {\r
-                                                       e.printStackTrace();\r
-                                               }\r
-                                       }\r
-                               }\r
-                               for (Statement s : changes.getDeletions()) {\r
-                                       String sub;\r
-                                       try {\r
-                                               \r
-                                               sub = NameUtils.getSafeName(graph, s.getSubject());\r
-                                               String pre = NameUtils.getSafeName(graph, s.getPredicate());\r
-                                               String obj = NameUtils.getSafeName(graph, s.getObject());\r
-                                               if (map.containsLeft(s)) {\r
-                                                       index++;\r
-                                                       indices.put(s, index);\r
-                                                       sb1.append("["+index + "] ");\r
-                                               }\r
-                                               sb1.append(sub + " - " + pre + " - " + obj);\r
-                                               sb1.append(" ["+s.getSubject().getResourceId() + " " + s.getPredicate().getResourceId() + " " + s.getObject().getResourceId()+"]");\r
-                                               sb1.append("\n");\r
-                                       } catch (ValidationException e) {\r
-                                               e.printStackTrace();\r
-                                       } catch (ServiceException e) {\r
-                                               e.printStackTrace();\r
-                                       }\r
-                                       \r
-                               }\r
-                               \r
-                               for (Statement s : changes.getAdditions()) {\r
-                                       String sub;\r
-                                       try {\r
-                                               sub = NameUtils.getSafeName(graph, s.getSubject());\r
-                                               String pre = NameUtils.getSafeName(graph, s.getPredicate());\r
-                                               String obj = NameUtils.getSafeName(graph, s.getObject());\r
-                                               if (map.containsRight(s)) {\r
-                                                       index = indices.get(map.getLeft(s));\r
-                                                       sb2.append("["+index + "] ");\r
-                                               }\r
-                                               sb2.append(sub + " - " + pre + " - " + obj);\r
-                                               sb2.append(" ["+s.getSubject().getResourceId() + " " + s.getPredicate().getResourceId() + " " + s.getObject().getResourceId()+"]");\r
-                                               sb2.append("\n");\r
-                                       } catch (ValidationException e) {\r
-                                               e.printStackTrace();\r
-                                       } catch (ServiceException e) {\r
-                                               e.printStackTrace();\r
-                                       }\r
-                                       \r
-                               }\r
-                               Display.getDefault().asyncExec(new Runnable() {                 \r
-                                       @Override\r
-                                       public void run() {\r
-                                               text1.setText(sb1.toString());\r
-                                               text2.setText(sb2.toString());\r
-                                               \r
-                                       }\r
-                               });\r
-                       }\r
-               });\r
-       }\r
-       \r
-       @Override\r
-       public void setFocus() {\r
-               composite.setFocus();\r
-       }\r
-       \r
-       @Override\r
-       public void dispose() {\r
-               super.dispose();\r
-               \r
-       }\r
-       \r
-       \r
-       // copy-paste from GraphDebugger\r
-        public Label createDropLabel(Composite parent) {\r
-               final Label label = new Label(parent, SWT.BORDER);\r
-               label.setAlignment(SWT.CENTER);\r
-               label.setText("Drag a resource here to examine it in this debugger!");\r
-               label.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));\r
-               GridData data = new GridData(SWT.FILL, SWT.TOP, true, false);\r
-               data.heightHint = 16;\r
-               label.setLayoutData(data);\r
-\r
-               // Add resource id drop support to the drop-area.\r
-               DropTarget dropTarget = new DropTarget(label, DND.DROP_LINK | DND.DROP_COPY);\r
-               dropTarget.setTransfer(new Transfer[] { TextTransfer.getInstance(), ResourceReferenceTransfer.getInstance(), LocalObjectTransfer.getTransfer() });\r
-               dropTarget.addDropListener(new DropTargetAdapter() {\r
-                   @Override\r
-                   public void dragEnter(DropTargetEvent event) {\r
-                       event.detail = DND.DROP_LINK;\r
-                       //label.setBackground(green);\r
-                       return;\r
-                   }\r
-                   @Override\r
-                   public void dragLeave(DropTargetEvent event) {\r
-                       label.setBackground(null);\r
-                   }\r
-\r
-                   @Override\r
-                   public void drop(DropTargetEvent event) {\r
-                       label.setBackground(null);\r
-                       ResourceArray[] data = parseEventData(event);\r
-                       if (data == null || data.length != 1) {\r
-                           event.detail = DND.DROP_NONE;\r
-                           return;\r
-                       }\r
-                       final ResourceArray array = data[0];\r
-                       final Resource r = array.resources[array.resources.length - 1];\r
-\r
-                       label.setData(r);\r
-                       try {\r
-                                               label.setText(session.syncRequest(new Read<String>() {\r
-                                                       @Override\r
-                                                       public String perform(ReadGraph graph)\r
-                                                               throws DatabaseException {\r
-                                                               return NameUtils.getSafeName(graph, r);\r
-                                                       }\r
-                                               }));\r
-                                       } catch (DatabaseException e) {\r
-                                               e.printStackTrace();\r
-                                       }\r
-                   }\r
-\r
-                   private ResourceArray[] parseEventData(DropTargetEvent event) {\r
-                       //System.out.println("DATA: " + event.data);\r
-                       if (event.data instanceof String) {\r
-                           try {\r
-                               SerialisationSupport support = session.getService(SerialisationSupport.class);\r
-                               return ResourceTransferUtils.readStringTransferable(support, (String) event.data).toResourceArrayArray();\r
-                           } catch (IllegalArgumentException e) {\r
-                               e.printStackTrace();\r
-                           } catch (DatabaseException e) {\r
-                               e.printStackTrace();\r
-                           } \r
-                       }\r
-                       ResourceArray[] ret = ResourceAdaptionUtils.toResourceArrays(event.data);\r
-                       if (ret.length > 0)\r
-                           return ret;\r
-                       return null;\r
-                   }\r
-               });\r
-\r
-               return label;\r
-           }\r
-       \r
-       \r
-       \r
-       private class ConfigurationDialog extends Dialog {\r
-\r
-               protected ConfigurationDialog(Shell parentShell) {\r
-                       super(parentShell);\r
-               }\r
-               \r
-               @Override\r
-               protected void createButtonsForButtonBar(Composite parent) {\r
-                       createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);\r
-                       createButton(parent, IDialogConstants.CLIENT_ID+1, "Load", false);\r
-                       createButton(parent, IDialogConstants.CLIENT_ID+2, "Save", false);\r
-               }\r
-               \r
-               @Override\r
-               protected void buttonPressed(int buttonId) {\r
-                       super.buttonPressed(buttonId);\r
-                       if (buttonId == IDialogConstants.CLIENT_ID+1) {\r
-                               //load\r
-                               FileDialog dialog = new FileDialog(Display.getCurrent().getActiveShell(),SWT.OPEN);\r
-                               dialog.setFilterExtensions(new String[]{"*.xml"});\r
-                               String filename = dialog.open();\r
-                               if (filename == null)\r
-                               return;\r
-                               try {\r
-                                       load(filename);\r
-                                       traversedViewer.refresh();\r
-                                       testedViewer.refresh();\r
-                                       strongViewer.refresh();\r
-                                       nonTestedViewer.refresh();\r
-                                       nonTraversedViewer.refresh();\r
-                               } catch (Exception e1) {\r
-                                       MessageDialog.openError(Display.getCurrent().getActiveShell(), "Cannot load file" , e1.getMessage());\r
-                               }\r
-                       } else if (buttonId == IDialogConstants.CLIENT_ID+2) {\r
-                               //save\r
-                               FileDialog dialog = new FileDialog(Display.getCurrent().getActiveShell(),SWT.SAVE);\r
-                       dialog.setFilterExtensions(new String[]{"*.xml"});\r
-                       String filename = dialog.open();\r
-                       if (filename == null)\r
-                               return;\r
-                       try {\r
-                               saveConf(filename);\r
-                               if (!filename.endsWith("xml")) \r
-                                       filename += ".xml";\r
-                       } catch (FileNotFoundException e1) {\r
-                               MessageDialog.openError(Display.getCurrent().getActiveShell(), "Cannot save file" , e1.getMessage());\r
-                               } catch (IOException e1) {\r
-                                       MessageDialog.openError(Display.getCurrent().getActiveShell(), "Cannot save file" , e1.getMessage());\r
-                               } catch (DatabaseException e1) {\r
-                                       MessageDialog.openError(Display.getCurrent().getActiveShell(), "Cannot save file" , e1.getMessage());\r
-                               }\r
-                       }\r
-               }\r
-               \r
-               private ListViewer traversedViewer;\r
-               private ListViewer testedViewer;\r
-               private ListViewer strongViewer;\r
-               private ListViewer nonTraversedViewer;\r
-               private ListViewer nonTestedViewer;\r
-               \r
-               @Override\r
-               protected Control createDialogArea(Composite parent) {\r
-                        Composite composite = (Composite) super.createDialogArea(parent);\r
-                        composite.setLayout(new FillLayout(SWT.VERTICAL));\r
-                        \r
-                        Group group = new Group(composite, SWT.NONE);\r
-                        group.setText("Traversed");\r
-                        group.setLayout(new FillLayout());\r
-                        traversedViewer = new ListViewer(group);\r
-                        \r
-                        group = new Group(composite, SWT.NONE);\r
-                        group.setText("Tested");\r
-                        group.setLayout(new FillLayout());\r
-                        testedViewer = new ListViewer(group);\r
-                        \r
-                        group = new Group(composite, SWT.NONE);\r
-                        group.setText("Strong");\r
-                        group.setLayout(new FillLayout());\r
-                        strongViewer = new ListViewer(group);\r
-                        \r
-                        group = new Group(composite, SWT.NONE);\r
-                        group.setText("NonTraversed");\r
-                        group.setLayout(new FillLayout());\r
-                        nonTraversedViewer = new ListViewer(group);\r
-                        \r
-                        group = new Group(composite, SWT.NONE);\r
-                        group.setText("NonTested");\r
-                        group.setLayout(new FillLayout());\r
-                        nonTestedViewer = new ListViewer(group);\r
-                        \r
-                        traversedViewer.setContentProvider(new ResourceListContentProvider());\r
-                        traversedViewer.setLabelProvider(new ResourceLabelProvider());\r
-                        \r
-                        testedViewer.setContentProvider(new ResourceListContentProvider());\r
-                        testedViewer.setLabelProvider(new ResourceLabelProvider());\r
-                        \r
-                        strongViewer.setContentProvider(new ResourceListContentProvider());\r
-                        strongViewer.setLabelProvider(new ResourceLabelProvider());\r
-                        \r
-                        nonTraversedViewer.setContentProvider(new ResourceListContentProvider());\r
-                        nonTraversedViewer.setLabelProvider(new ResourceLabelProvider());\r
-                        \r
-                        nonTestedViewer.setContentProvider(new ResourceListContentProvider());\r
-                        nonTestedViewer.setLabelProvider(new ResourceLabelProvider());\r
-                        \r
-                        MenuManager strongManager = new MenuManager();\r
-                        strongManager.setRemoveAllWhenShown(true);\r
-                        strongManager.addMenuListener(new ListPopupListener(strongViewer));\r
-                        strongViewer.getControl().setMenu(strongManager.createContextMenu(strongViewer.getControl()));\r
-                        \r
-                        MenuManager nonTestedManager = new MenuManager();\r
-                        nonTestedManager.setRemoveAllWhenShown(true);\r
-                        nonTestedManager.addMenuListener(new ListPopupListener(nonTestedViewer));\r
-                        nonTestedViewer.getControl().setMenu(nonTestedManager.createContextMenu(nonTestedViewer.getControl()));\r
-                        \r
-                        MenuManager nonTraversedManager = new MenuManager();\r
-                        nonTraversedManager.setRemoveAllWhenShown(true);\r
-                        nonTraversedManager.addMenuListener(new ListPopupListener(nonTraversedViewer));\r
-                        nonTraversedViewer.getControl().setMenu(nonTraversedManager.createContextMenu(nonTraversedViewer.getControl()));\r
-                        \r
-                        MenuManager testedManager = new MenuManager();\r
-                        testedManager.setRemoveAllWhenShown(true);\r
-                        testedManager.addMenuListener(new ListPopupListener(testedViewer));\r
-                        testedViewer.getControl().setMenu(testedManager.createContextMenu(testedViewer.getControl()));\r
-                        \r
-                        MenuManager traversedManager = new MenuManager();\r
-                        traversedManager.setRemoveAllWhenShown(true);\r
-                        traversedManager.addMenuListener(new ListPopupListener(traversedViewer));\r
-                        traversedViewer.getControl().setMenu(traversedManager.createContextMenu(traversedViewer.getControl()));\r
-                        \r
-                        traversedViewer.setInput(traversed);\r
-                        testedViewer.setInput(tested);\r
-                        strongViewer.setInput(strong);\r
-                        nonTestedViewer.setInput(nonTested);\r
-                        nonTraversedViewer.setInput(nonTraversed);\r
-                        \r
-                        return composite;\r
-               }\r
-               \r
-       }\r
-       \r
-       private class ListPopupListener implements IMenuListener {\r
-               private ListViewer viewer;\r
-               \r
-               public ListPopupListener(ListViewer viewer) {\r
-                       this.viewer = viewer;\r
-               }\r
-               \r
-               @Override\r
-               public void menuAboutToShow(IMenuManager manager) {\r
-                       IStructuredSelection s = (IStructuredSelection)viewer.getSelection();\r
-                       List<Object> list = (List<Object>)viewer.getInput();\r
-                       manager.add(new AddAction(viewer, list));\r
-                       if (!s.isEmpty()) {\r
-                               Object element = s.getFirstElement();\r
-                               manager.add(new DeleteAction(viewer, list, element));\r
-                       }\r
-                       \r
-               }\r
-       }\r
-       \r
-       private class DeleteAction extends Action {\r
-               private Viewer viewer;\r
-               private List<?> list;\r
-               private Object obj;\r
-               public DeleteAction(Viewer viewer, List<?> list, Object obj) {\r
-                       super("Delete");\r
-                       this.list = list;\r
-                       this.obj = obj;\r
-                       this.viewer = viewer;\r
-               }\r
-               \r
-               @Override\r
-               public void run() {\r
-                       list.remove(obj);\r
-                       viewer.refresh();\r
-               }\r
-       }\r
-       \r
-       private class AddAction extends Action {\r
-               private Viewer viewer;\r
-               private List<Object> list;\r
-               public AddAction(Viewer viewer, List<Object> list) {\r
-                       super("Add");\r
-                       this.list = list;\r
-                       this.viewer = viewer;\r
-               }\r
-               \r
-               @Override\r
-               public void run() {\r
-                       RelationChooseDialog dialog = new RelationChooseDialog(getSite().getShell());\r
-                       if (dialog.open() == RelationChooseDialog.OK) {\r
-                               final String uri = dialog.getUri();\r
-                               try {\r
-                                       Resource res = session.syncRequest(new Read<Resource>() {\r
-                                               @Override\r
-                                               public Resource perform(ReadGraph graph)\r
-                                                               throws DatabaseException {\r
-                                                       try {\r
-                                                               return graph.getResource(uri);\r
-                                                       } catch (Exception e) {\r
-                                                               return null;\r
-                                                       }\r
-                                               }\r
-                                       });\r
-                                       if (res != null) {\r
-                                               list.add(res);\r
-                                               viewer.refresh();\r
-                                       } else {\r
-                                               MessageDialog.openError(getSite().getShell(), "Error", "Relation '" + uri + "' not found.");\r
-                                       }\r
-                               } catch (Exception e) {\r
-                                       \r
-                               }\r
-                               \r
-                               \r
-                       }\r
-                       \r
-               }\r
-       }\r
-       \r
-       private class RelationChooseDialog extends Dialog {\r
-\r
-               private String uri = null;\r
-               private Text text;\r
-               public RelationChooseDialog(IShellProvider parentShell) {\r
-                       super(parentShell);\r
-               }\r
-\r
-               public RelationChooseDialog(Shell parentShell) {\r
-                       super(parentShell);\r
-               }\r
-               \r
-               @Override\r
-               protected Control createDialogArea(Composite parent) {\r
-                       Composite composite = (Composite) super.createDialogArea(parent);\r
-                       composite.setLayout(new GridLayout(2, false));\r
-                       Label label = new Label(composite, SWT.NONE);\r
-                       label.setText("URI:");\r
-                       \r
-                       text = new Text(composite, SWT.SINGLE | SWT.BORDER);\r
-                       text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));\r
-                       \r
-                       return composite;\r
-               }\r
-               \r
-               @Override\r
-               protected void okPressed() {\r
-                       uri = text.getText();\r
-                       super.okPressed();\r
-               }\r
-               \r
-               public String getUri() {\r
-                       return uri;\r
-               }\r
-               \r
-       }\r
-       \r
-       private class ResourceListContentProvider implements IStructuredContentProvider {\r
-               \r
-               @SuppressWarnings("unchecked")\r
-               @Override\r
-               public Object[] getElements(Object inputElement) {\r
-                       List<Resource> list = (List<Resource>)inputElement;\r
-                       return list.toArray();\r
-               }\r
-               \r
-               @Override\r
-               public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {\r
-                       \r
-               }\r
-               \r
-               @Override\r
-               public void dispose() {\r
-                       \r
-               }\r
-       }\r
-       \r
-       private class ResourceLabelProvider extends LabelProvider {\r
-               \r
-               @Override\r
-               public String getText(Object element) {\r
-                       final Resource res = (Resource) element; \r
-                       try {\r
-                               return session.syncRequest(new Read<String>() {\r
-                                       @Override\r
-                                       public String perform(ReadGraph graph) throws DatabaseException {\r
-                                               return NameUtils.getSafeName(graph, res);\r
-                                       }\r
-                               });\r
-                       } catch (DatabaseException e) {\r
-                               return "Error: " + e.getMessage();\r
-                       }\r
-               }\r
-               \r
-       }\r
-       \r
-       private boolean saveConf(String filename) throws IOException, DatabaseException {\r
-               File file = new File(filename);\r
-               if (file.exists()) {\r
-                       if(!MessageDialog.openQuestion(Display.getCurrent().getActiveShell(), "Saving compare configuration", "Do you want to overwrite file'" + filename + "'?"))\r
-                               return false;   \r
-               } else {\r
-                       if(!file.createNewFile())\r
-                               return false;\r
-               }\r
-               final PrintStream ps = new PrintStream(file);\r
-               ps.println("<?xml version=\"1.0\"?>");\r
-               ps.println("<compare>");\r
-               session.syncRequest(new ReadRequest() {\r
-                       \r
-                       @Override\r
-                       public void run(ReadGraph graph) throws DatabaseException {\r
-                               for (Resource r : traversed) {\r
-                                       ps.println("<traversed uri=\"" + graph.getURI(r) + "\"/>");\r
-                               }\r
-                               for (Resource r : tested) {\r
-                                       ps.println("<tested uri=\"" + graph.getURI(r) + "\"/>");\r
-                               }\r
-                               for (Resource r : strong) {\r
-                                       ps.println("<strong uri=\"" + graph.getURI(r) + "\"/>");\r
-                               }\r
-                               for (Resource r : nonTraversed) {\r
-                                       ps.println("<nontraversed uri=\"" + graph.getURI(r) + "\"/>");\r
-                               }\r
-                               for (Resource r : nonTested) {\r
-                                       ps.println("<nontested uri=\"" + graph.getURI(r) + "\"/>");\r
-                               }\r
-                       }\r
-               });\r
-               \r
-               ps.println("</compare>");\r
-               ps.flush();\r
-               ps.close();\r
-               return true;\r
-       }\r
-       \r
-       private void load(String filename) throws Exception {\r
-               final ImportListener listener = new ImportListener();\r
-               XMLParser parser = new XMLParser(listener);\r
-               parser.parse(filename);\r
-               \r
-               if (listener.getNonTested().size() +\r
-                       listener.getNonTraversed().size() +\r
-                       listener.getStrong().size() +\r
-                       listener.getTested().size() +\r
-                       listener.getTraversed().size() == 0)\r
-                       return;\r
-               session.syncRequest(new ReadRequest() {\r
-                       \r
-                       @Override\r
-                       public void run(ReadGraph graph) throws DatabaseException {\r
-                               tested.clear();\r
-                               traversed.clear();\r
-                               strong.clear();\r
-                               nonTested.clear();\r
-                               nonTraversed.clear();\r
-                               for (String uri : listener.getTested()) {\r
-                                       tested.add(graph.getResource(uri));\r
-                               }\r
-                               for (String uri : listener.getTraversed()) {\r
-                                       traversed.add(graph.getResource(uri));\r
-                               }\r
-                               for (String uri : listener.getStrong()) {\r
-                                       strong.add(graph.getResource(uri));\r
-                               }\r
-                               \r
-                               for (String uri : listener.getNonTested()) {\r
-                                       nonTested.add(graph.getResource(uri));\r
-                               }\r
-                               for (String uri : listener.getNonTraversed()) {\r
-                                       nonTraversed.add(graph.getResource(uri));\r
-                               }\r
-                               \r
-                       }\r
-               });\r
-               \r
-               \r
-               \r
-       }\r
-       \r
-       public static class ImportListener {\r
-               \r
-       \r
-               private Collection<String> traversed = new ArrayList<String>();\r
-               private Collection<String> tested = new ArrayList<String>();\r
-               private Collection<String> strong = new ArrayList<String>();\r
-               private Collection<String> nonTraversed = new ArrayList<String>();\r
-               private Collection<String> nonTested = new ArrayList<String>();\r
-               \r
-\r
-               public void done() {\r
-\r
-               }\r
-               \r
-               \r
-               public void addTraversed(String uri) {\r
-                       traversed.add(uri);\r
-               }\r
-               \r
-               public void addTested(String uri) {\r
-                       tested.add(uri);\r
-               }\r
-               \r
-               public void addStrong(String uri) {\r
-                       strong.add(uri);\r
-               }\r
-               \r
-               public void addNonTraversed(String uri) {\r
-                       nonTraversed.add(uri);\r
-               }\r
-               \r
-               public void addNonTested(String uri) {\r
-                       nonTested.add(uri);\r
-               }\r
-               \r
-               public Collection<String> getTraversed() {\r
-                       return traversed;\r
-               }\r
-               \r
-               public Collection<String> getNonTested() {\r
-                       return nonTested;\r
-               }\r
-               \r
-               public Collection<String> getNonTraversed() {\r
-                       return nonTraversed;\r
-               }\r
-               \r
-               public Collection<String> getStrong() {\r
-                       return strong;\r
-               }\r
-               \r
-               public Collection<String> getTested() {\r
-                       return tested;\r
-               }\r
-               \r
-       }\r
-       \r
-       \r
-\r
-       public static class XMLParser {\r
-               \r
-               private ImportListener listener;\r
-               \r
-               public XMLParser(ImportListener listener) {\r
-                       this.listener = listener;\r
-               }\r
-               \r
-               public void parse(String filename) throws Exception{\r
-                       ParserBean p = new ParserBean();\r
-                       p.parse(filename);\r
-               }\r
-               \r
-               private void handleElement(Stack<Element> parents, Element element) throws SAXException{\r
-                       String name = element.qName;\r
-                       if(name.equals("traversed")) {\r
-                               for (Attribute a : element.attributes) {\r
-                                       String propertyName = a.localName;\r
-                                       String value = a.value;\r
-                                       if (propertyName.equals("uri")) {\r
-                                               listener.addTraversed(value);\r
-                                               \r
-                                       } \r
-                               }\r
-                       } else if(name.equals("tested")) {\r
-                               for (Attribute a : element.attributes) {\r
-                                       String propertyName = a.localName;\r
-                                       String value = a.value;\r
-                                       if (propertyName.equals("uri")) {\r
-                                               listener.addTested(value);\r
-                                               \r
-                                       } \r
-                               }\r
-                       } else if(name.equals("strong")) {\r
-                               for (Attribute a : element.attributes) {\r
-                                       String propertyName = a.localName;\r
-                                       String value = a.value;\r
-                                       if (propertyName.equals("uri")) {\r
-                                               listener.addStrong(value);\r
-                                               \r
-                                       } \r
-                               }\r
-                       } else if(name.equals("nontraversed")) {\r
-                               for (Attribute a : element.attributes) {\r
-                                       String propertyName = a.localName;\r
-                                       String value = a.value;\r
-                                       if (propertyName.equals("uri")) {\r
-                                               listener.addNonTraversed(value);\r
-                                               \r
-                                       } \r
-                               }\r
-                       } else if(name.equals("nontested")) {\r
-                               for (Attribute a : element.attributes) {\r
-                                       String propertyName = a.localName;\r
-                                       String value = a.value;\r
-                                       if (propertyName.equals("uri")) {\r
-                                               listener.addNonTested(value);\r
-                                               \r
-                                       } \r
-                               }\r
-                       } else if (name.equals("compare")) {\r
-                               \r
-                       } else {\r
-                               throw new SAXException("Unknown element '" + name + "'. The file does not contain ExtIO configuration.");\r
-                               \r
-                       }\r
-               }\r
-\r
-               \r
-               public class ParserBean extends DefaultHandler implements Serializable {\r
-\r
-                       private static final long serialVersionUID = -4995836637014958966L;\r
-                       \r
-                       private Stack<Element> current = new Stack<Element>();\r
-                       private Stack<String> texts = new Stack<String>();\r
-                       \r
-                       public ParserBean() {\r
-                               super();\r
-                       }\r
-                       \r
-                       public void parse(String filename) throws Exception {\r
-                               SAXParserFactory spf = SAXParserFactory.newInstance();\r
-                               SAXParser saxParser = spf.newSAXParser();\r
-                               \r
-                               XMLReader reader = saxParser.getXMLReader();\r
-                               FileReader file = new FileReader(filename);\r
-                               reader.setContentHandler(this);\r
-                               reader.parse(new InputSource(file));\r
-                               listener.done();\r
-                       }\r
-                       \r
-                       @Override\r
-                       public void startElement(String uri, String localName, String name,\r
-                                       Attributes attributes) throws SAXException {\r
-                               current.push(new Element(uri,localName,name,attributes));\r
-                               texts.push(new String());\r
-                       }\r
-                       \r
-                       @Override\r
-                       public void endElement(String uri, String localName, String name)\r
-                                       throws SAXException {\r
-                               Element e = null;\r
-                               String text = null;\r
-                               if (!current.empty()) {\r
-                                       e = current.pop();\r
-                                       text = texts.pop();\r
-                               }\r
-                               if (e != null) {\r
-                                       e.setValue(text.trim());\r
-                               }\r
-                               if (e != null) {\r
-                                       handleElement(current,e);\r
-                               }\r
-                       }\r
-                       \r
-                       @Override\r
-                       public void characters(char[] ch, int start, int length)\r
-                                       throws SAXException {\r
-                               if (!current.empty()) {\r
-                                       \r
-                                       String text = texts.pop();\r
-                                       \r
-                                       String value = new String(\r
-                               ch, start, length);\r
-                               text += value;\r
-                               texts.push(text);\r
-                            }\r
-                       }\r
-               }\r
-               \r
-               public class Attribute {\r
-                       public String localName;\r
-                       public String qName;\r
-                       public String uri;\r
-                       public String value;\r
-                       \r
-                       public Attribute(String localName, String qName, String uri, String value) {\r
-                               this.localName = localName;\r
-                               this.qName = qName;\r
-                               this.uri = uri;\r
-                               this.value = value;\r
-                       }\r
-               }\r
-               \r
-               public class Element implements Serializable {\r
-                       private static final long serialVersionUID = -5207502156942818875L;\r
-                       String uri;\r
-                       String localName;\r
-                       String qName;\r
-                       String value = null;\r
-                       List<Attribute> attributes = new ArrayList<Attribute>();\r
-                       \r
-                       public Element(String uri, String localName, String qName, Attributes attributes) {\r
-                               this.uri = uri;\r
-                               this.localName = localName;\r
-                               this.qName = qName;\r
-                               for (int i = 0; i < attributes.getLength(); i++) {\r
-                                       this.attributes.add(new Attribute(attributes.getLocalName(i),attributes.getQName(i),attributes.getURI(i),attributes.getValue(i)));\r
-                               }\r
-                       }\r
-\r
-                       public String getUri() {\r
-                               return uri;\r
-                       }\r
-\r
-                       public String getLocalName() {\r
-                               return localName;\r
-                       }\r
-\r
-                       public String getQName() {\r
-                               return qName;\r
-                       }\r
-\r
-                       public String getValue() {\r
-                               return value;\r
-                       }\r
-\r
-                       public List<Attribute> getAttributes() {\r
-                               return attributes;\r
-                       }\r
-                       \r
-                       public void setValue(String value) {\r
-                               this.value = value;\r
-                       }\r
-\r
-               }\r
-\r
-       }\r
-       \r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Foster Wheeler Energia Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.interop.test;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.ListViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.window.IShellProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DropTarget;
+import org.eclipse.swt.dnd.DropTargetAdapter;
+import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.part.ViewPart;
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.Statement;
+import org.simantics.db.common.ResourceArray;
+import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.common.utils.NameUtils;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.exception.ServiceException;
+import org.simantics.db.exception.ValidationException;
+import org.simantics.db.request.Read;
+import org.simantics.db.service.SerialisationSupport;
+import org.simantics.interop.test.GraphChanges.Modification;
+import org.simantics.layer0.Layer0;
+import org.simantics.ui.dnd.LocalObjectTransfer;
+import org.simantics.ui.dnd.ResourceReferenceTransfer;
+import org.simantics.ui.dnd.ResourceTransferUtils;
+import org.simantics.ui.utils.ResourceAdaptionUtils;
+import org.simantics.utils.datastructures.BijectionMap;
+import org.simantics.utils.datastructures.Pair;
+import org.simantics.utils.ui.ExceptionUtils;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Simple multiline text viewer for seeing differences in two subgraphs. 
+ * 
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
+ *
+ */
+public class GraphComparatorViewer extends ViewPart{
+       
+       private Session session;
+
+       private Composite composite;
+       
+       private Label resourceText1;
+       private Label resourceText2;
+       
+       private Text text1;
+       private Text text2;
+       
+       
+       private List<Resource> traversed = new ArrayList<Resource>();
+       private List<Resource> tested = new ArrayList<Resource>();
+       private List<Resource> strong = new ArrayList<Resource>();
+       private List<Resource> nonTraversed = new ArrayList<Resource>();
+       private List<Resource> nonTested = new ArrayList<Resource>();
+
+       
+       @Override
+       public void createPartControl(Composite parent) {
+               composite = new Composite(parent, SWT.NONE);
+               composite.setLayout(new GridLayout(2, false));
+               
+               session = Simantics.getSession();
+               
+               Composite topComposite = new Composite(composite, SWT.BORDER);
+               topComposite.setLayout(new GridLayout(3, false));
+               text1 = new Text(composite, SWT.MULTI|SWT.V_SCROLL);
+               text2 = new Text(composite, SWT.MULTI|SWT.V_SCROLL);
+               
+               GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP).grab(true, false).span(2, 1).applyTo(topComposite);
+               GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(text1);
+               GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(text2);
+               
+               resourceText1 = createDropLabel(topComposite);
+               resourceText2 = createDropLabel(topComposite);
+               
+               Button button = new Button(topComposite, SWT.PUSH);
+               button.setText("Compare");
+               button.addSelectionListener(new SelectionAdapter() {
+                       @Override
+                       public void widgetSelected(SelectionEvent e) {
+                               compare();
+                       }
+               });
+               
+               defaultConf();
+               
+               getViewSite().getActionBars().getToolBarManager().add(new Action("Config") {
+                       @Override
+                       public void run() {
+                               ConfigurationDialog dialog = new ConfigurationDialog(getSite().getShell());
+                               dialog.open();
+                       }
+               });
+               
+       }
+       
+       private void defaultConf() {
+               traversed.clear();
+               tested.clear();
+               strong.clear();
+               nonTested.clear();
+               nonTraversed.clear();
+               try {
+               session.syncRequest(new ReadRequest() {
+                       @Override
+                       public void run(ReadGraph graph) throws DatabaseException {
+                               Layer0 l0 = Layer0.getInstance(graph);
+                               traversed.add(l0.ConsistsOf);
+                               tested.add(l0.IsWeaklyRelatedTo);
+                               nonTraversed.add(l0.InstanceOf);
+                       }
+               });
+               } catch (Exception e) {
+                       ExceptionUtils.logAndShowError(e);
+               }
+       }
+       
+       private void compare() {
+               text1.setText("");
+               text2.setText("");
+               final Resource r1 = (Resource)resourceText1.getData();
+               final Resource r2 = (Resource)resourceText2.getData();
+               if (r1 == null || r2 == null) {
+                       if (r1 == null)
+                               text1.setText("Missing input!");
+                       if (r2 == null)
+                               text2.setText("Missing input!");
+                       return; 
+               }
+               
+               session.asyncRequest(new ReadRequest() {
+                       
+                       @Override
+                       public void run(final ReadGraph graph) throws DatabaseException {
+                               GraphComparator comparator = new GraphComparator(r1,r2);
+                               
+                               comparator.addTested(tested);
+                               comparator.addTraversed(traversed);
+                               comparator.addNonTested(nonTested);
+                               comparator.addNonTraversed(nonTraversed);
+                               comparator.addStrong(strong);
+                               
+                               comparator.test(graph);
+                               BijectionMap<Statement, Statement> map = comparator.getComparableStatements();
+                               Map<Statement, Integer> indices = new HashMap<Statement, Integer>();
+                               final StringBuilder sb1 = new StringBuilder();
+                               final StringBuilder sb2 = new StringBuilder();
+                               int index = 0;
+                               
+                               GraphChanges changes = comparator.getChanges();
+                               
+                               for (Modification mod : changes.getModifications()) {
+                                       {
+                                               String sub;
+                                               try {
+                                                       Statement s = mod.getLeftStm();
+                                                       sub = NameUtils.getSafeName(graph, mod.getLeftSub());
+                                                       String pre = NameUtils.getSafeName(graph, s.getPredicate());
+                                                       String obj = NameUtils.getSafeName(graph, s.getObject());
+                                                       if (map.containsLeft(s)) {
+                                                               index++;
+                                                               indices.put(s, index);
+                                                               sb1.append("["+index + "] ");
+                                                       }
+                                                       sb1.append(sub + " - " + pre + " - " + obj);
+                                                       sb1.append(" ["+s.getSubject().getResourceId() + " " + s.getPredicate().getResourceId() + " " + s.getObject().getResourceId()+"]");
+                                                       sb1.append("\n");
+                                               } catch (ValidationException e) {
+                                                       e.printStackTrace();
+                                               } catch (ServiceException e) {
+                                                       e.printStackTrace();
+                                               }
+                                       }
+                                       {
+                                               String sub;
+                                               try {
+                                                       Statement s = mod.getRightStm();
+                                                       sub = NameUtils.getSafeName(graph, mod.getRightSub());
+                                                       String pre = NameUtils.getSafeName(graph, s.getPredicate());
+                                                       String obj = NameUtils.getSafeName(graph, s.getObject());
+                                                       if (map.containsRight(s)) {
+                                                               index = indices.get(map.getLeft(s));
+                                                               sb2.append("["+index + "] ");
+                                                       }
+                                                       sb2.append(sub + " - " + pre + " - " + obj);
+                                                       sb2.append(" ["+s.getSubject().getResourceId() + " " + s.getPredicate().getResourceId() + " " + s.getObject().getResourceId()+"]");
+                                                       sb2.append("\n");
+                                               } catch (ValidationException e) {
+                                                       e.printStackTrace();
+                                               } catch (ServiceException e) {
+                                                       e.printStackTrace();
+                                               }
+                                       }
+                               }
+                               for (Statement s : changes.getDeletions()) {
+                                       String sub;
+                                       try {
+                                               
+                                               sub = NameUtils.getSafeName(graph, s.getSubject());
+                                               String pre = NameUtils.getSafeName(graph, s.getPredicate());
+                                               String obj = NameUtils.getSafeName(graph, s.getObject());
+                                               if (map.containsLeft(s)) {
+                                                       index++;
+                                                       indices.put(s, index);
+                                                       sb1.append("["+index + "] ");
+                                               }
+                                               sb1.append(sub + " - " + pre + " - " + obj);
+                                               sb1.append(" ["+s.getSubject().getResourceId() + " " + s.getPredicate().getResourceId() + " " + s.getObject().getResourceId()+"]");
+                                               sb1.append("\n");
+                                       } catch (ValidationException e) {
+                                               e.printStackTrace();
+                                       } catch (ServiceException e) {
+                                               e.printStackTrace();
+                                       }
+                                       
+                               }
+                               
+                               for (Statement s : changes.getAdditions()) {
+                                       String sub;
+                                       try {
+                                               sub = NameUtils.getSafeName(graph, s.getSubject());
+                                               String pre = NameUtils.getSafeName(graph, s.getPredicate());
+                                               String obj = NameUtils.getSafeName(graph, s.getObject());
+                                               if (map.containsRight(s)) {
+                                                       index = indices.get(map.getLeft(s));
+                                                       sb2.append("["+index + "] ");
+                                               }
+                                               sb2.append(sub + " - " + pre + " - " + obj);
+                                               sb2.append(" ["+s.getSubject().getResourceId() + " " + s.getPredicate().getResourceId() + " " + s.getObject().getResourceId()+"]");
+                                               sb2.append("\n");
+                                       } catch (ValidationException e) {
+                                               e.printStackTrace();
+                                       } catch (ServiceException e) {
+                                               e.printStackTrace();
+                                       }
+                                       
+                               }
+                               Display.getDefault().asyncExec(new Runnable() {                 
+                                       @Override
+                                       public void run() {
+                                               text1.setText(sb1.toString());
+                                               text2.setText(sb2.toString());
+                                               
+                                       }
+                               });
+                       }
+               });
+       }
+       
+       @Override
+       public void setFocus() {
+               composite.setFocus();
+       }
+       
+       @Override
+       public void dispose() {
+               super.dispose();
+               
+       }
+       
+       
+       // copy-paste from GraphDebugger
+        public Label createDropLabel(Composite parent) {
+               final Label label = new Label(parent, SWT.BORDER);
+               label.setAlignment(SWT.CENTER);
+               label.setText("Drag a resource here to examine it in this debugger!");
+               label.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));
+               GridData data = new GridData(SWT.FILL, SWT.TOP, true, false);
+               data.heightHint = 16;
+               label.setLayoutData(data);
+
+               // Add resource id drop support to the drop-area.
+               DropTarget dropTarget = new DropTarget(label, DND.DROP_LINK | DND.DROP_COPY);
+               dropTarget.setTransfer(new Transfer[] { TextTransfer.getInstance(), ResourceReferenceTransfer.getInstance(), LocalObjectTransfer.getTransfer() });
+               dropTarget.addDropListener(new DropTargetAdapter() {
+                   @Override
+                   public void dragEnter(DropTargetEvent event) {
+                       event.detail = DND.DROP_LINK;
+                       //label.setBackground(green);
+                       return;
+                   }
+                   @Override
+                   public void dragLeave(DropTargetEvent event) {
+                       label.setBackground(null);
+                   }
+
+                   @Override
+                   public void drop(DropTargetEvent event) {
+                       label.setBackground(null);
+                       ResourceArray[] data = parseEventData(event);
+                       if (data == null || data.length != 1) {
+                           event.detail = DND.DROP_NONE;
+                           return;
+                       }
+                       final ResourceArray array = data[0];
+                       final Resource r = array.resources[array.resources.length - 1];
+
+                       label.setData(r);
+                       try {
+                                               label.setText(session.syncRequest(new Read<String>() {
+                                                       @Override
+                                                       public String perform(ReadGraph graph)
+                                                               throws DatabaseException {
+                                                               return NameUtils.getSafeName(graph, r);
+                                                       }
+                                               }));
+                                       } catch (DatabaseException e) {
+                                               e.printStackTrace();
+                                       }
+                   }
+
+                   private ResourceArray[] parseEventData(DropTargetEvent event) {
+                       //System.out.println("DATA: " + event.data);
+                       if (event.data instanceof String) {
+                           try {
+                               SerialisationSupport support = session.getService(SerialisationSupport.class);
+                               return ResourceTransferUtils.readStringTransferable(support, (String) event.data).toResourceArrayArray();
+                           } catch (IllegalArgumentException e) {
+                               e.printStackTrace();
+                           } catch (DatabaseException e) {
+                               e.printStackTrace();
+                           } 
+                       }
+                       ResourceArray[] ret = ResourceAdaptionUtils.toResourceArrays(event.data);
+                       if (ret.length > 0)
+                           return ret;
+                       return null;
+                   }
+               });
+
+               return label;
+           }
+       
+       
+       
+       private class ConfigurationDialog extends Dialog {
+
+               protected ConfigurationDialog(Shell parentShell) {
+                       super(parentShell);
+               }
+               
+               @Override
+               protected void createButtonsForButtonBar(Composite parent) {
+                       createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
+                       createButton(parent, IDialogConstants.CLIENT_ID+1, "Load", false);
+                       createButton(parent, IDialogConstants.CLIENT_ID+2, "Save", false);
+               }
+               
+               @Override
+               protected void buttonPressed(int buttonId) {
+                       super.buttonPressed(buttonId);
+                       if (buttonId == IDialogConstants.CLIENT_ID+1) {
+                               //load
+                               FileDialog dialog = new FileDialog(Display.getCurrent().getActiveShell(),SWT.OPEN);
+                               dialog.setFilterExtensions(new String[]{"*.xml"});
+                               String filename = dialog.open();
+                               if (filename == null)
+                               return;
+                               try {
+                                       load(filename);
+                                       traversedViewer.refresh();
+                                       testedViewer.refresh();
+                                       strongViewer.refresh();
+                                       nonTestedViewer.refresh();
+                                       nonTraversedViewer.refresh();
+                               } catch (Exception e1) {
+                                       MessageDialog.openError(Display.getCurrent().getActiveShell(), "Cannot load file" , e1.getMessage());
+                               }
+                       } else if (buttonId == IDialogConstants.CLIENT_ID+2) {
+                               //save
+                               FileDialog dialog = new FileDialog(Display.getCurrent().getActiveShell(),SWT.SAVE);
+                       dialog.setFilterExtensions(new String[]{"*.xml"});
+                       String filename = dialog.open();
+                       if (filename == null)
+                               return;
+                       try {
+                               saveConf(filename);
+                               if (!filename.endsWith("xml")) 
+                                       filename += ".xml";
+                       } catch (FileNotFoundException e1) {
+                               MessageDialog.openError(Display.getCurrent().getActiveShell(), "Cannot save file" , e1.getMessage());
+                               } catch (IOException e1) {
+                                       MessageDialog.openError(Display.getCurrent().getActiveShell(), "Cannot save file" , e1.getMessage());
+                               } catch (DatabaseException e1) {
+                                       MessageDialog.openError(Display.getCurrent().getActiveShell(), "Cannot save file" , e1.getMessage());
+                               }
+                       }
+               }
+               
+               private ListViewer traversedViewer;
+               private ListViewer testedViewer;
+               private ListViewer strongViewer;
+               private ListViewer nonTraversedViewer;
+               private ListViewer nonTestedViewer;
+               
+               @Override
+               protected Control createDialogArea(Composite parent) {
+                        Composite composite = (Composite) super.createDialogArea(parent);
+                        composite.setLayout(new FillLayout(SWT.VERTICAL));
+                        
+                        Group group = new Group(composite, SWT.NONE);
+                        group.setText("Traversed");
+                        group.setLayout(new FillLayout());
+                        traversedViewer = new ListViewer(group);
+                        
+                        group = new Group(composite, SWT.NONE);
+                        group.setText("Tested");
+                        group.setLayout(new FillLayout());
+                        testedViewer = new ListViewer(group);
+                        
+                        group = new Group(composite, SWT.NONE);
+                        group.setText("Strong");
+                        group.setLayout(new FillLayout());
+                        strongViewer = new ListViewer(group);
+                        
+                        group = new Group(composite, SWT.NONE);
+                        group.setText("NonTraversed");
+                        group.setLayout(new FillLayout());
+                        nonTraversedViewer = new ListViewer(group);
+                        
+                        group = new Group(composite, SWT.NONE);
+                        group.setText("NonTested");
+                        group.setLayout(new FillLayout());
+                        nonTestedViewer = new ListViewer(group);
+                        
+                        traversedViewer.setContentProvider(new ResourceListContentProvider());
+                        traversedViewer.setLabelProvider(new ResourceLabelProvider());
+                        
+                        testedViewer.setContentProvider(new ResourceListContentProvider());
+                        testedViewer.setLabelProvider(new ResourceLabelProvider());
+                        
+                        strongViewer.setContentProvider(new ResourceListContentProvider());
+                        strongViewer.setLabelProvider(new ResourceLabelProvider());
+                        
+                        nonTraversedViewer.setContentProvider(new ResourceListContentProvider());
+                        nonTraversedViewer.setLabelProvider(new ResourceLabelProvider());
+                        
+                        nonTestedViewer.setContentProvider(new ResourceListContentProvider());
+                        nonTestedViewer.setLabelProvider(new ResourceLabelProvider());
+                        
+                        MenuManager strongManager = new MenuManager();
+                        strongManager.setRemoveAllWhenShown(true);
+                        strongManager.addMenuListener(new ListPopupListener(strongViewer));
+                        strongViewer.getControl().setMenu(strongManager.createContextMenu(strongViewer.getControl()));
+                        
+                        MenuManager nonTestedManager = new MenuManager();
+                        nonTestedManager.setRemoveAllWhenShown(true);
+                        nonTestedManager.addMenuListener(new ListPopupListener(nonTestedViewer));
+                        nonTestedViewer.getControl().setMenu(nonTestedManager.createContextMenu(nonTestedViewer.getControl()));
+                        
+                        MenuManager nonTraversedManager = new MenuManager();
+                        nonTraversedManager.setRemoveAllWhenShown(true);
+                        nonTraversedManager.addMenuListener(new ListPopupListener(nonTraversedViewer));
+                        nonTraversedViewer.getControl().setMenu(nonTraversedManager.createContextMenu(nonTraversedViewer.getControl()));
+                        
+                        MenuManager testedManager = new MenuManager();
+                        testedManager.setRemoveAllWhenShown(true);
+                        testedManager.addMenuListener(new ListPopupListener(testedViewer));
+                        testedViewer.getControl().setMenu(testedManager.createContextMenu(testedViewer.getControl()));
+                        
+                        MenuManager traversedManager = new MenuManager();
+                        traversedManager.setRemoveAllWhenShown(true);
+                        traversedManager.addMenuListener(new ListPopupListener(traversedViewer));
+                        traversedViewer.getControl().setMenu(traversedManager.createContextMenu(traversedViewer.getControl()));
+                        
+                        traversedViewer.setInput(traversed);
+                        testedViewer.setInput(tested);
+                        strongViewer.setInput(strong);
+                        nonTestedViewer.setInput(nonTested);
+                        nonTraversedViewer.setInput(nonTraversed);
+                        
+                        return composite;
+               }
+               
+       }
+       
+       private class ListPopupListener implements IMenuListener {
+               private ListViewer viewer;
+               
+               public ListPopupListener(ListViewer viewer) {
+                       this.viewer = viewer;
+               }
+               
+               @Override
+               public void menuAboutToShow(IMenuManager manager) {
+                       IStructuredSelection s = (IStructuredSelection)viewer.getSelection();
+                       List<Object> list = (List<Object>)viewer.getInput();
+                       manager.add(new AddAction(viewer, list));
+                       if (!s.isEmpty()) {
+                               Object element = s.getFirstElement();
+                               manager.add(new DeleteAction(viewer, list, element));
+                       }
+                       
+               }
+       }
+       
+       private class DeleteAction extends Action {
+               private Viewer viewer;
+               private List<?> list;
+               private Object obj;
+               public DeleteAction(Viewer viewer, List<?> list, Object obj) {
+                       super("Delete");
+                       this.list = list;
+                       this.obj = obj;
+                       this.viewer = viewer;
+               }
+               
+               @Override
+               public void run() {
+                       list.remove(obj);
+                       viewer.refresh();
+               }
+       }
+       
+       private class AddAction extends Action {
+               private Viewer viewer;
+               private List<Object> list;
+               public AddAction(Viewer viewer, List<Object> list) {
+                       super("Add");
+                       this.list = list;
+                       this.viewer = viewer;
+               }
+               
+               @Override
+               public void run() {
+                       RelationChooseDialog dialog = new RelationChooseDialog(getSite().getShell());
+                       if (dialog.open() == RelationChooseDialog.OK) {
+                               final String uri = dialog.getUri();
+                               try {
+                                       Resource res = session.syncRequest(new Read<Resource>() {
+                                               @Override
+                                               public Resource perform(ReadGraph graph)
+                                                               throws DatabaseException {
+                                                       try {
+                                                               return graph.getResource(uri);
+                                                       } catch (Exception e) {
+                                                               return null;
+                                                       }
+                                               }
+                                       });
+                                       if (res != null) {
+                                               list.add(res);
+                                               viewer.refresh();
+                                       } else {
+                                               MessageDialog.openError(getSite().getShell(), "Error", "Relation '" + uri + "' not found.");
+                                       }
+                               } catch (Exception e) {
+                                       
+                               }
+                               
+                               
+                       }
+                       
+               }
+       }
+       
+       private class RelationChooseDialog extends Dialog {
+
+               private String uri = null;
+               private Text text;
+               public RelationChooseDialog(IShellProvider parentShell) {
+                       super(parentShell);
+               }
+
+               public RelationChooseDialog(Shell parentShell) {
+                       super(parentShell);
+               }
+               
+               @Override
+               protected Control createDialogArea(Composite parent) {
+                       Composite composite = (Composite) super.createDialogArea(parent);
+                       composite.setLayout(new GridLayout(2, false));
+                       Label label = new Label(composite, SWT.NONE);
+                       label.setText("URI:");
+                       
+                       text = new Text(composite, SWT.SINGLE | SWT.BORDER);
+                       text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+                       
+                       return composite;
+               }
+               
+               @Override
+               protected void okPressed() {
+                       uri = text.getText();
+                       super.okPressed();
+               }
+               
+               public String getUri() {
+                       return uri;
+               }
+               
+       }
+       
+       private class ResourceListContentProvider implements IStructuredContentProvider {
+               
+               @SuppressWarnings("unchecked")
+               @Override
+               public Object[] getElements(Object inputElement) {
+                       List<Resource> list = (List<Resource>)inputElement;
+                       return list.toArray();
+               }
+               
+               @Override
+               public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+                       
+               }
+               
+               @Override
+               public void dispose() {
+                       
+               }
+       }
+       
+       private class ResourceLabelProvider extends LabelProvider {
+               
+               @Override
+               public String getText(Object element) {
+                       final Resource res = (Resource) element; 
+                       try {
+                               return session.syncRequest(new Read<String>() {
+                                       @Override
+                                       public String perform(ReadGraph graph) throws DatabaseException {
+                                               return NameUtils.getSafeName(graph, res);
+                                       }
+                               });
+                       } catch (DatabaseException e) {
+                               return "Error: " + e.getMessage();
+                       }
+               }
+               
+       }
+       
+       private boolean saveConf(String filename) throws IOException, DatabaseException {
+               File file = new File(filename);
+               if (file.exists()) {
+                       if(!MessageDialog.openQuestion(Display.getCurrent().getActiveShell(), "Saving compare configuration", "Do you want to overwrite file'" + filename + "'?"))
+                               return false;   
+               } else {
+                       if(!file.createNewFile())
+                               return false;
+               }
+               final PrintStream ps = new PrintStream(file);
+               ps.println("<?xml version=\"1.0\"?>");
+               ps.println("<compare>");
+               session.syncRequest(new ReadRequest() {
+                       
+                       @Override
+                       public void run(ReadGraph graph) throws DatabaseException {
+                               for (Resource r : traversed) {
+                                       ps.println("<traversed uri=\"" + graph.getURI(r) + "\"/>");
+                               }
+                               for (Resource r : tested) {
+                                       ps.println("<tested uri=\"" + graph.getURI(r) + "\"/>");
+                               }
+                               for (Resource r : strong) {
+                                       ps.println("<strong uri=\"" + graph.getURI(r) + "\"/>");
+                               }
+                               for (Resource r : nonTraversed) {
+                                       ps.println("<nontraversed uri=\"" + graph.getURI(r) + "\"/>");
+                               }
+                               for (Resource r : nonTested) {
+                                       ps.println("<nontested uri=\"" + graph.getURI(r) + "\"/>");
+                               }
+                       }
+               });
+               
+               ps.println("</compare>");
+               ps.flush();
+               ps.close();
+               return true;
+       }
+       
+       private void load(String filename) throws Exception {
+               final ImportListener listener = new ImportListener();
+               XMLParser parser = new XMLParser(listener);
+               parser.parse(filename);
+               
+               if (listener.getNonTested().size() +
+                       listener.getNonTraversed().size() +
+                       listener.getStrong().size() +
+                       listener.getTested().size() +
+                       listener.getTraversed().size() == 0)
+                       return;
+               session.syncRequest(new ReadRequest() {
+                       
+                       @Override
+                       public void run(ReadGraph graph) throws DatabaseException {
+                               tested.clear();
+                               traversed.clear();
+                               strong.clear();
+                               nonTested.clear();
+                               nonTraversed.clear();
+                               for (String uri : listener.getTested()) {
+                                       tested.add(graph.getResource(uri));
+                               }
+                               for (String uri : listener.getTraversed()) {
+                                       traversed.add(graph.getResource(uri));
+                               }
+                               for (String uri : listener.getStrong()) {
+                                       strong.add(graph.getResource(uri));
+                               }
+                               
+                               for (String uri : listener.getNonTested()) {
+                                       nonTested.add(graph.getResource(uri));
+                               }
+                               for (String uri : listener.getNonTraversed()) {
+                                       nonTraversed.add(graph.getResource(uri));
+                               }
+                               
+                       }
+               });
+               
+               
+               
+       }
+       
+       public static class ImportListener {
+               
+       
+               private Collection<String> traversed = new ArrayList<String>();
+               private Collection<String> tested = new ArrayList<String>();
+               private Collection<String> strong = new ArrayList<String>();
+               private Collection<String> nonTraversed = new ArrayList<String>();
+               private Collection<String> nonTested = new ArrayList<String>();
+               
+
+               public void done() {
+
+               }
+               
+               
+               public void addTraversed(String uri) {
+                       traversed.add(uri);
+               }
+               
+               public void addTested(String uri) {
+                       tested.add(uri);
+               }
+               
+               public void addStrong(String uri) {
+                       strong.add(uri);
+               }
+               
+               public void addNonTraversed(String uri) {
+                       nonTraversed.add(uri);
+               }
+               
+               public void addNonTested(String uri) {
+                       nonTested.add(uri);
+               }
+               
+               public Collection<String> getTraversed() {
+                       return traversed;
+               }
+               
+               public Collection<String> getNonTested() {
+                       return nonTested;
+               }
+               
+               public Collection<String> getNonTraversed() {
+                       return nonTraversed;
+               }
+               
+               public Collection<String> getStrong() {
+                       return strong;
+               }
+               
+               public Collection<String> getTested() {
+                       return tested;
+               }
+               
+       }
+       
+       
+
+       public static class XMLParser {
+               
+               private ImportListener listener;
+               
+               public XMLParser(ImportListener listener) {
+                       this.listener = listener;
+               }
+               
+               public void parse(String filename) throws Exception{
+                       ParserBean p = new ParserBean();
+                       p.parse(filename);
+               }
+               
+               private void handleElement(Stack<Element> parents, Element element) throws SAXException{
+                       String name = element.qName;
+                       if(name.equals("traversed")) {
+                               for (Attribute a : element.attributes) {
+                                       String propertyName = a.localName;
+                                       String value = a.value;
+                                       if (propertyName.equals("uri")) {
+                                               listener.addTraversed(value);
+                                               
+                                       } 
+                               }
+                       } else if(name.equals("tested")) {
+                               for (Attribute a : element.attributes) {
+                                       String propertyName = a.localName;
+                                       String value = a.value;
+                                       if (propertyName.equals("uri")) {
+                                               listener.addTested(value);
+                                               
+                                       } 
+                               }
+                       } else if(name.equals("strong")) {
+                               for (Attribute a : element.attributes) {
+                                       String propertyName = a.localName;
+                                       String value = a.value;
+                                       if (propertyName.equals("uri")) {
+                                               listener.addStrong(value);
+                                               
+                                       } 
+                               }
+                       } else if(name.equals("nontraversed")) {
+                               for (Attribute a : element.attributes) {
+                                       String propertyName = a.localName;
+                                       String value = a.value;
+                                       if (propertyName.equals("uri")) {
+                                               listener.addNonTraversed(value);
+                                               
+                                       } 
+                               }
+                       } else if(name.equals("nontested")) {
+                               for (Attribute a : element.attributes) {
+                                       String propertyName = a.localName;
+                                       String value = a.value;
+                                       if (propertyName.equals("uri")) {
+                                               listener.addNonTested(value);
+                                               
+                                       } 
+                               }
+                       } else if (name.equals("compare")) {
+                               
+                       } else {
+                               throw new SAXException("Unknown element '" + name + "'. The file does not contain ExtIO configuration.");
+                               
+                       }
+               }
+
+               
+               public class ParserBean extends DefaultHandler implements Serializable {
+
+                       private static final long serialVersionUID = -4995836637014958966L;
+                       
+                       private Stack<Element> current = new Stack<Element>();
+                       private Stack<String> texts = new Stack<String>();
+                       
+                       public ParserBean() {
+                               super();
+                       }
+                       
+                       public void parse(String filename) throws Exception {
+                               SAXParserFactory spf = SAXParserFactory.newInstance();
+                               SAXParser saxParser = spf.newSAXParser();
+                               
+                               XMLReader reader = saxParser.getXMLReader();
+                               FileReader file = new FileReader(filename);
+                               reader.setContentHandler(this);
+                               reader.parse(new InputSource(file));
+                               listener.done();
+                       }
+                       
+                       @Override
+                       public void startElement(String uri, String localName, String name,
+                                       Attributes attributes) throws SAXException {
+                               current.push(new Element(uri,localName,name,attributes));
+                               texts.push(new String());
+                       }
+                       
+                       @Override
+                       public void endElement(String uri, String localName, String name)
+                                       throws SAXException {
+                               Element e = null;
+                               String text = null;
+                               if (!current.empty()) {
+                                       e = current.pop();
+                                       text = texts.pop();
+                               }
+                               if (e != null) {
+                                       e.setValue(text.trim());
+                               }
+                               if (e != null) {
+                                       handleElement(current,e);
+                               }
+                       }
+                       
+                       @Override
+                       public void characters(char[] ch, int start, int length)
+                                       throws SAXException {
+                               if (!current.empty()) {
+                                       
+                                       String text = texts.pop();
+                                       
+                                       String value = new String(
+                               ch, start, length);
+                               text += value;
+                               texts.push(text);
+                            }
+                       }
+               }
+               
+               public class Attribute {
+                       public String localName;
+                       public String qName;
+                       public String uri;
+                       public String value;
+                       
+                       public Attribute(String localName, String qName, String uri, String value) {
+                               this.localName = localName;
+                               this.qName = qName;
+                               this.uri = uri;
+                               this.value = value;
+                       }
+               }
+               
+               public class Element implements Serializable {
+                       private static final long serialVersionUID = -5207502156942818875L;
+                       String uri;
+                       String localName;
+                       String qName;
+                       String value = null;
+                       List<Attribute> attributes = new ArrayList<Attribute>();
+                       
+                       public Element(String uri, String localName, String qName, Attributes attributes) {
+                               this.uri = uri;
+                               this.localName = localName;
+                               this.qName = qName;
+                               for (int i = 0; i < attributes.getLength(); i++) {
+                                       this.attributes.add(new Attribute(attributes.getLocalName(i),attributes.getQName(i),attributes.getURI(i),attributes.getValue(i)));
+                               }
+                       }
+
+                       public String getUri() {
+                               return uri;
+                       }
+
+                       public String getLocalName() {
+                               return localName;
+                       }
+
+                       public String getQName() {
+                               return qName;
+                       }
+
+                       public String getValue() {
+                               return value;
+                       }
+
+                       public List<Attribute> getAttributes() {
+                               return attributes;
+                       }
+                       
+                       public void setValue(String value) {
+                               this.value = value;
+                       }
+
+               }
+
+       }
+       
+}