]> gerrit.simantics Code Review - simantics/interop.git/commitdiff
refs #3169
authorluukkainen <luukkainen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Thu, 26 Jan 2012 16:17:55 +0000 (16:17 +0000)
committerMarko Luukkainen <marko.luukkainen@vtt.fi>
Thu, 2 Feb 2017 09:22:18 +0000 (11:22 +0200)
git-svn-id: https://www.simantics.org/svn/simantics/interoperability/trunk@24062 ac1ea38d-2e2b-0410-8846-a27921b304fc

12 files changed:
org.simantics.interop/META-INF/MANIFEST.MF
org.simantics.interop/plugin.xml
org.simantics.interop/src/org/simantics/interop/issues/AbstractIssue.java [deleted file]
org.simantics.interop/src/org/simantics/interop/issues/AndRead.java [deleted file]
org.simantics.interop/src/org/simantics/interop/issues/BasicIssue.java [deleted file]
org.simantics.interop/src/org/simantics/interop/issues/GraphIssue.java [deleted file]
org.simantics.interop/src/org/simantics/interop/issues/Issue.java [deleted file]
org.simantics.interop/src/org/simantics/interop/issues/IssueListener.java [deleted file]
org.simantics.interop/src/org/simantics/interop/issues/IssueReporter.java [deleted file]
org.simantics.interop/src/org/simantics/interop/issues/IssueReporterListener.java [deleted file]
org.simantics.interop/src/org/simantics/interop/ui/IssuesViewPart.java [deleted file]
org.simantics.interop/src/org/simantics/interop/utils/LinkedBijectionMap.java [new file with mode: 0644]

index cc325d769ee488ec3b3a4c8e6d48d3b253cce01d..677e9e48a4b6b1d68c593e251288978e9035c1f9 100644 (file)
@@ -25,7 +25,6 @@ Require-Bundle: org.eclipse.ui,
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Bundle-ActivationPolicy: lazy
 Export-Package: org.simantics.interop.browsing,
- org.simantics.interop.issues,
  org.simantics.interop.stubs,
  org.simantics.interop.test,
  org.simantics.interop.utils
index 729df964051f048256470f03214e1427a201f91c..17ac122c42cf512fa1d7882faf06f9b684809cf0 100644 (file)
             name="Comparator"\r
             restorable="true">\r
       </view>\r
-      <view\r
-            class="org.simantics.interop.ui.IssuesViewPart"\r
-            icon="platform:/plugin/com.famfamfam.silk/icons/building_error.png"\r
-            id="org.simantics.interop.issues"\r
-            name="Issues"\r
-            restorable="true">\r
-      </view>\r
    </extension>\r
    <extension\r
          point="org.eclipse.ui.importWizards">\r
diff --git a/org.simantics.interop/src/org/simantics/interop/issues/AbstractIssue.java b/org.simantics.interop/src/org/simantics/interop/issues/AbstractIssue.java
deleted file mode 100644 (file)
index 01ebb02..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-package org.simantics.interop.issues;\r
-\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-import org.eclipse.swt.widgets.Display;\r
-\r
-public abstract class AbstractIssue implements Issue{\r
-       \r
-       private String description;\r
-       private List<IssueListener> listeners =  new ArrayList<IssueListener>();\r
-       \r
-       @Override\r
-       public String getDescription() {\r
-               return description;\r
-       }\r
-       \r
-       public void setDescription(String description) {\r
-               this.description = description;\r
-               fireUpdated();\r
-       }\r
-       \r
-       protected void fireUpdated() {\r
-               Display.getDefault().asyncExec(new Runnable() {\r
-                       @Override\r
-                       public void run() {\r
-                               synchronized (listeners) {\r
-                                       for (IssueListener l : listeners) {\r
-                                               l.updated(AbstractIssue.this);\r
-                                       }       \r
-                               }\r
-                               \r
-                       }\r
-               });\r
-       }\r
-       \r
-       protected void fireDisposed() {\r
-               Display.getDefault().asyncExec(new Runnable() {\r
-                       @Override\r
-                       public void run() {\r
-                               List<IssueListener> list = new ArrayList<IssueListener>();\r
-                               list.addAll(listeners);\r
-                               for (IssueListener l : list) {\r
-                                       l.disposed(AbstractIssue.this);\r
-                               }\r
-                               listeners.clear();\r
-                       }\r
-               });\r
-       }\r
-       \r
-       @Override\r
-       public void addListener(IssueListener listener) {\r
-               synchronized(listeners) {\r
-                       listeners.add(listener);\r
-               }\r
-       }\r
-       \r
-       @Override\r
-       public void removeListener(IssueListener listener) {\r
-               synchronized(listeners) {\r
-                       listeners.remove(listener);\r
-               }\r
-       }\r
-       \r
-       @Override\r
-       public void dispose() {\r
-               fireDisposed();\r
-       }\r
-\r
-}\r
diff --git a/org.simantics.interop/src/org/simantics/interop/issues/AndRead.java b/org.simantics.interop/src/org/simantics/interop/issues/AndRead.java
deleted file mode 100644 (file)
index e8a28c0..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.simantics.interop.issues;\r
-\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.request.Read;\r
-\r
-/**\r
- * AndRead can be used to combine multiple requests into single one. If all reads return true or null, this returns true.\r
- * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
- *\r
- */\r
-public class AndRead implements Read<Boolean>{\r
-\r
-       private Read<Boolean> reads[];\r
-       \r
-       public AndRead(Read<Boolean>... reads) {\r
-               this.reads = reads;\r
-       }\r
-       \r
-       @Override\r
-       public Boolean perform(ReadGraph graph) throws DatabaseException {\r
-               Boolean b = null;\r
-               for (Read<Boolean> r : reads) {\r
-                       b = r.perform(graph);\r
-                       if(b != null && !b)\r
-                               return false;\r
-               }\r
-               return true;\r
-       }\r
-}\r
diff --git a/org.simantics.interop/src/org/simantics/interop/issues/BasicIssue.java b/org.simantics.interop/src/org/simantics/interop/issues/BasicIssue.java
deleted file mode 100644 (file)
index 12020ab..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.simantics.interop.issues;\r
-\r
-/**\r
- * Basic, static issue.\r
- * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
- *\r
- */\r
-public class BasicIssue extends AbstractIssue {\r
-\r
-       \r
-       public BasicIssue(String description) {\r
-               setDescription(description);\r
-       }\r
-       \r
-       @Override\r
-       public void showInEditor() {\r
-               \r
-       }\r
-       \r
-       @Override\r
-       public boolean supportsEditor() {\r
-               return false;\r
-       }\r
-       \r
-       \r
-}\r
diff --git a/org.simantics.interop/src/org/simantics/interop/issues/GraphIssue.java b/org.simantics.interop/src/org/simantics/interop/issues/GraphIssue.java
deleted file mode 100644 (file)
index 2a37603..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-package org.simantics.interop.issues;\r
-\r
-import org.simantics.db.AsyncReadGraph;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.procedure.AsyncListener;\r
-import org.simantics.db.request.Read;\r
-import org.simantics.utils.ui.ErrorLogger;\r
-\r
-/**\r
- * An issue whose state can be updated with an query\r
- * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
- *\r
- */\r
-public class GraphIssue extends AbstractIssue {\r
-       \r
-       private boolean disposed = false;\r
-       \r
-       /**\r
-        * Creates an new Graph Issue\r
-        * @param g access to graph\r
-        * @param request Request that returns true if issue is still valid. If the request returns false, the issue is disposed.\r
-        * @param description\r
-        */\r
-       public GraphIssue(ReadGraph g, Read<Boolean> request, String description) {\r
-               setDescription(description);\r
-               IssueReporter.getInstance().addIssue(this);\r
-               setRequest(g, request);\r
-       }\r
-       \r
-       public GraphIssue(String description) {\r
-               setDescription(description);\r
-               IssueReporter.getInstance().addIssue(this);\r
-       }\r
-       \r
-       public void setRequest(ReadGraph g, Read<Boolean> request) {\r
-               g.asyncRequest(request,new AsyncListener<Boolean>() {\r
-                       @Override\r
-                       public void execute(AsyncReadGraph graph, Boolean result) {\r
-                               if (result == null)\r
-                                       return;\r
-                               \r
-                               if (!result) {\r
-                                       dispose();\r
-                               }\r
-                       }\r
-                       \r
-                       @Override\r
-                       public void exception(AsyncReadGraph graph, Throwable throwable) {\r
-                               ErrorLogger.defaultLogError("Error in GraphIssue handling, disposing issue \"" + getDescription()+"\"", throwable);\r
-                               dispose();      \r
-                       }\r
-                       \r
-                       @Override\r
-                       public boolean isDisposed() {\r
-                               return disposed;\r
-                       }\r
-               });\r
-       }\r
-       \r
-       @Override\r
-       public void showInEditor() {\r
-       \r
-       }\r
-       \r
-       @Override\r
-       public boolean supportsEditor() {\r
-               return false;\r
-       }\r
-       \r
-       @Override\r
-       public void dispose() {\r
-               this.disposed = true;\r
-               super.dispose();\r
-       }\r
-\r
-}\r
diff --git a/org.simantics.interop/src/org/simantics/interop/issues/Issue.java b/org.simantics.interop/src/org/simantics/interop/issues/Issue.java
deleted file mode 100644 (file)
index 8d7a072..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.simantics.interop.issues;\r
-\r
-/**\r
- * Interface for an issue\r
- * \r
- * TODO: grouping, severity?\r
- * \r
- * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
- *\r
- */\r
-public interface Issue {\r
-       \r
-       /**\r
-        * Prints description\r
-        * @return\r
-        */\r
-       public String getDescription();\r
-       \r
-       /**\r
-        * Returns true if this issue can be highlighted in an editor\r
-        * @return\r
-        */\r
-       public boolean supportsEditor();\r
-       \r
-       /**\r
-        * Opens and highlights the reason of the issue in an editor\r
-        */\r
-       public void showInEditor();\r
-       \r
-       /**\r
-        * Disposes the issue.\r
-        */\r
-       public void dispose();\r
-       \r
-       public void addListener(IssueListener listenr);\r
-       public void removeListener(IssueListener listener);\r
-\r
-}\r
diff --git a/org.simantics.interop/src/org/simantics/interop/issues/IssueListener.java b/org.simantics.interop/src/org/simantics/interop/issues/IssueListener.java
deleted file mode 100644 (file)
index 0750afd..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.simantics.interop.issues;\r
-\r
-/**\r
- * Interface for listening changes in issues.\r
- * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
- *\r
- */\r
-public interface IssueListener {\r
-       \r
-       /**\r
-        * Issues is updated\r
-        * @param issue\r
-        */\r
-       public void updated(Issue issue);\r
-       \r
-       /**\r
-        * Issue is disposed (not valid anymore);\r
-        * @param issue\r
-        */\r
-       public void disposed(Issue issue);\r
-\r
-}\r
diff --git a/org.simantics.interop/src/org/simantics/interop/issues/IssueReporter.java b/org.simantics.interop/src/org/simantics/interop/issues/IssueReporter.java
deleted file mode 100644 (file)
index f1ab4a7..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-package org.simantics.interop.issues;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collections;\r
-import java.util.List;\r
-\r
-import org.eclipse.swt.widgets.Display;\r
-\r
-/**\r
- * IssueReporter is singleton class that handles collecting issues.\r
- * \r
- * TODO: how to store issues when the application is closed? Memento-based?\r
- * \r
- * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
- *\r
- */\r
-public class IssueReporter implements IssueListener{\r
-       \r
-       private static IssueReporter INSTANCE;\r
-       \r
-       private List<Issue> issues = new ArrayList<Issue>();\r
-       private List<IssueReporterListener> listeners = new ArrayList<IssueReporterListener>();\r
-       \r
-       \r
-       private IssueReporter() {\r
-               \r
-       }\r
-       \r
-       public static IssueReporter getInstance() {\r
-               if (INSTANCE == null)\r
-                       INSTANCE = new IssueReporter();\r
-               return INSTANCE;\r
-       }\r
-       \r
-       /**\r
-        * Retuns list of issues.\r
-        * @return\r
-        */\r
-       public List<Issue> getIssues() {\r
-               return Collections.unmodifiableList(issues);\r
-       }\r
-       \r
-       public void addIssue(Issue issue) {\r
-               issues.add(issue);\r
-               issue.addListener(this);\r
-               fireAdded(issue);\r
-       }\r
-       \r
-       public void removeIssue(Issue issue) {\r
-               issue.removeListener(this);\r
-               issues.remove(issue);\r
-               fireRemoved(issue);\r
-       }\r
-       \r
-       @Override\r
-       public void updated(Issue issue) {\r
-               fireUpdated(issue);\r
-       }\r
-       \r
-       @Override\r
-       public void disposed(Issue issue) {\r
-               issue.removeListener(this);\r
-               issues.remove(issue);\r
-               fireRemoved(issue);\r
-       }\r
-       \r
-       \r
-       public void addListener(IssueReporterListener listener) {\r
-               listeners.add(listener);\r
-       }\r
-       \r
-       public void removeListener(IssueReporterListener listener) {\r
-               listeners.remove(listener);\r
-       }\r
-       \r
-       protected void fireAdded(final Issue issue) {\r
-               Display.getDefault().asyncExec(new Runnable() {\r
-                       @Override\r
-                       public void run() {\r
-                               for (IssueReporterListener l : listeners)\r
-                                       l.added(issue);\r
-                       }\r
-               });\r
-       }\r
-       \r
-       protected void fireRemoved(final Issue issue) {\r
-               Display.getDefault().asyncExec(new Runnable() {\r
-                       @Override\r
-                       public void run() {\r
-                               for (IssueReporterListener l : listeners)\r
-                                       l.removed(issue);\r
-                       }\r
-               });\r
-       }\r
-       \r
-       protected void fireUpdated(final Issue issue) {\r
-               Display.getDefault().asyncExec(new Runnable() {\r
-                       @Override\r
-                       public void run() {\r
-                               for (IssueReporterListener l : listeners)\r
-                                       l.updated(issue);\r
-                       }\r
-               });\r
-       }\r
-       \r
-\r
-}\r
diff --git a/org.simantics.interop/src/org/simantics/interop/issues/IssueReporterListener.java b/org.simantics.interop/src/org/simantics/interop/issues/IssueReporterListener.java
deleted file mode 100644 (file)
index 8b15040..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.simantics.interop.issues;\r
-\r
-public interface IssueReporterListener {\r
-       \r
-       public void added(Issue issue);\r
-       public void removed(Issue issue);\r
-       public void updated(Issue issue);\r
-\r
-}\r
diff --git a/org.simantics.interop/src/org/simantics/interop/ui/IssuesViewPart.java b/org.simantics.interop/src/org/simantics/interop/ui/IssuesViewPart.java
deleted file mode 100644 (file)
index a481623..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-package org.simantics.interop.ui;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.List;\r
-\r
-import org.eclipse.jface.viewers.ILabelProviderListener;\r
-import org.eclipse.jface.viewers.IStructuredContentProvider;\r
-import org.eclipse.jface.viewers.IStructuredSelection;\r
-import org.eclipse.jface.viewers.ITableLabelProvider;\r
-import org.eclipse.jface.viewers.TableViewer;\r
-import org.eclipse.jface.viewers.Viewer;\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.events.SelectionAdapter;\r
-import org.eclipse.swt.events.SelectionEvent;\r
-import org.eclipse.swt.graphics.Image;\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.ui.part.ViewPart;\r
-import org.simantics.interop.issues.Issue;\r
-import org.simantics.interop.issues.IssueReporter;\r
-import org.simantics.interop.issues.IssueReporterListener;\r
-\r
-public class IssuesViewPart extends ViewPart {\r
-\r
-       private Composite parent;\r
-       private TableViewer viewer;\r
-       \r
-       \r
-       public IssuesViewPart() {\r
-               // TODO Auto-generated constructor stub\r
-       }\r
-\r
-       @Override\r
-       public void createPartControl(Composite parent) {\r
-               this.parent = parent;\r
-               this.parent.setLayout(new GridLayout(1,false));\r
-               viewer = new TableViewer(parent);\r
-               viewer.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));\r
-               viewer.setContentProvider(new IssueContentProvider());\r
-               viewer.setLabelProvider(new IssueLabelProvider());\r
-               \r
-               viewer.setInput(IssueReporter.getInstance().getIssues());\r
-               \r
-               Composite buttonComposite = new Composite(parent, SWT.BORDER);\r
-               buttonComposite.setLayout(new FillLayout(SWT.HORIZONTAL));\r
-               Button clearButton = new Button(buttonComposite, SWT.PUSH);\r
-               clearButton.setText("Clear all");\r
-               clearButton.addSelectionListener(new SelectionAdapter() {\r
-                       @Override\r
-                       public void widgetSelected(SelectionEvent e) {\r
-                               Collection<Issue> issues = IssueReporter.getInstance().getIssues();\r
-                               for (Issue i : issues)\r
-                                       i.dispose();\r
-                       }\r
-               });\r
-               \r
-               Button showButton = new Button(buttonComposite, SWT.PUSH);\r
-               showButton.setText("Show in editor");\r
-               showButton.addSelectionListener(new SelectionAdapter() {\r
-                       @Override\r
-                       public void widgetSelected(SelectionEvent e) {\r
-                               IStructuredSelection sel = (IStructuredSelection)viewer.getSelection();\r
-                               if (sel.isEmpty())\r
-                                       return;\r
-                               Issue i = (Issue)sel.getFirstElement();\r
-                               if (i.supportsEditor())\r
-                                       i.showInEditor();\r
-                       }\r
-               });\r
-               \r
-               \r
-       }\r
-\r
-       @Override\r
-       public void setFocus() {\r
-               parent.setFocus();\r
-       }\r
-       \r
-       \r
-       private class IssueContentProvider implements IStructuredContentProvider {\r
-               private IssueReporterListener listener;\r
-               private Viewer viewer;\r
-               \r
-               public IssueContentProvider() {\r
-                       listener = new IssueReporterListener() {\r
-                       \r
-                               @Override\r
-                               public void updated(Issue issue) {\r
-                                       viewer.refresh();\r
-                               }\r
-                       \r
-                               @Override\r
-                               public void removed(Issue issue) {\r
-                                       viewer.setInput(IssueReporter.getInstance().getIssues());\r
-                               }\r
-                       \r
-                               @Override\r
-                               public void added(Issue issue) {\r
-                                       viewer.setInput(IssueReporter.getInstance().getIssues());\r
-                               }\r
-                       };\r
-                       IssueReporter.getInstance().addListener(listener);\r
-               }\r
-               \r
-               \r
-               @SuppressWarnings("unchecked")\r
-               @Override\r
-               public Object[] getElements(Object inputElement) {\r
-                       Collection<Issue> issues = (Collection<Issue>)inputElement;\r
-                       return issues.toArray();\r
-               }\r
-               \r
-               @Override\r
-               public void dispose() {\r
-                       IssueReporter.getInstance().removeListener(listener);\r
-               }\r
-               \r
-               @Override\r
-               public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {\r
-                       this.viewer = viewer;\r
-               }\r
-       }\r
-       \r
-       private class IssueLabelProvider implements ITableLabelProvider {\r
-               \r
-               private List<ILabelProviderListener> listeners = new ArrayList<ILabelProviderListener>();\r
-               \r
-               @Override\r
-               public Image getColumnImage(Object element, int columnIndex) {\r
-                       return null;\r
-               }\r
-               \r
-               @Override\r
-               public String getColumnText(Object element, int columnIndex) {\r
-                       Issue issue = (Issue)element;\r
-                       if (columnIndex == 0)\r
-                               return issue.getDescription();\r
-                       return null;\r
-               }\r
-               \r
-               @Override\r
-               public boolean isLabelProperty(Object element, String property) {\r
-                       return true;\r
-               }\r
-               \r
-               @Override\r
-               public void addListener(ILabelProviderListener listener) {\r
-                       listeners.add(listener);\r
-               }\r
-               \r
-               @Override\r
-               public void removeListener(ILabelProviderListener listener) {\r
-                       listeners.remove(listener);\r
-               }\r
-               \r
-               @Override\r
-               public void dispose() {\r
-                       \r
-               }\r
-       }\r
-\r
-}\r
diff --git a/org.simantics.interop/src/org/simantics/interop/utils/LinkedBijectionMap.java b/org.simantics.interop/src/org/simantics/interop/utils/LinkedBijectionMap.java
new file mode 100644 (file)
index 0000000..cfe6997
--- /dev/null
@@ -0,0 +1,212 @@
+package org.simantics.interop.utils;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.LinkedHashMap;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.Map.Entry;\r
+\r
+import org.simantics.utils.datastructures.BijectionMap;\r
+\r
+public class LinkedBijectionMap<L, R> {\r
+       /** The keys of tableLeft are left-side-values and\r
+     * values are right-side-values */\r
+    private final Map<L, R> tableLeft = new LinkedHashMap<L, R>();\r
+    /** The keys of tableRight are right-side-values and\r
+     * values on it are left-side-values */\r
+    private final Map<R, L> tableRight = new LinkedHashMap<R, L>();\r
+\r
+    /** The keys of tableLeft are left-side-values and\r
+     * values are right-side-values */\r
+    private final Map<L, R> imTableLeft = Collections.unmodifiableMap(tableLeft);\r
+    /** The keys of tableRight are right-side-values and\r
+     * values on it are left-side-values */\r
+    private final Map<R, L> imTableRight = Collections.unmodifiableMap(tableRight);\r
+\r
+    private final Set<L> imLeftSet = Collections.unmodifiableSet(tableLeft.keySet());\r
+    private final Set<R> imRightSet = Collections.unmodifiableSet(tableRight.keySet());\r
+\r
+       public LinkedBijectionMap() {\r
+\r
+       }\r
+\r
+       public LinkedBijectionMap(LinkedBijectionMap<L, R> copyFrom) {\r
+               this.tableLeft.putAll(copyFrom.tableLeft);\r
+               this.tableRight.putAll(copyFrom.tableRight);\r
+       }\r
+\r
+       public void addAll(BijectionMap<L, R> map)\r
+       {\r
+               for (Entry<L, R> e : map.getEntries())\r
+                       map(e.getKey(), e.getValue());\r
+       }\r
+\r
+    public boolean retainAllLeft(Collection<L> values)\r
+    {\r
+        boolean result = false;\r
+        Collection<L> remove = new ArrayList<L>(size());\r
+        for (L lValue : imLeftSet) {\r
+            if (!values.contains(lValue)) {\r
+                remove.add(lValue);\r
+                result = true;\r
+            }\r
+        }\r
+        if (!remove.isEmpty()) {\r
+            for (L lValue : remove)\r
+                removeWithLeft(lValue);\r
+        }\r
+        return result;\r
+    }\r
+\r
+    public boolean retainAllRight(Collection<R> values)\r
+    {\r
+        boolean result = false;\r
+        Collection<R> remove = new ArrayList<R>(size());\r
+        for (R rValue : imRightSet) {\r
+            if (!values.contains(rValue)) {\r
+                remove.add(rValue);\r
+                result = true;\r
+            }\r
+        }\r
+        if (!remove.isEmpty()) {\r
+            for (R rValue : remove)\r
+                removeWithRight(rValue);\r
+        }\r
+        return result;\r
+    }\r
+\r
+       public Set<Entry<L, R>> getEntries()\r
+       {\r
+               return tableLeft.entrySet();\r
+       }\r
+\r
+       public boolean containsLeft(L leftValue)\r
+       {\r
+               return tableLeft.containsKey(leftValue);\r
+       }\r
+\r
+       public boolean containsRight(R rightValue)\r
+       {\r
+               return tableRight.containsKey(rightValue);\r
+       }\r
+\r
+       public boolean contains(L leftValue, R rightValue)\r
+       {\r
+               if (leftValue==null || rightValue==null) return false;\r
+               return rightValue.equals(tableLeft.get(leftValue));\r
+       }\r
+\r
+       public void map(L leftValue, R rightValue)\r
+       {\r
+        if (leftValue == null || rightValue == null)\r
+            throw new NullPointerException();\r
+        // Remove possible old mapping\r
+        R oldRight = tableLeft.remove(leftValue);\r
+        if (oldRight != null) {\r
+            tableRight.remove(oldRight);\r
+        } else {\r
+            L oldLeft = tableRight.remove(rightValue);\r
+            if (oldLeft != null) {\r
+                tableLeft.remove(oldLeft);\r
+            }\r
+        }\r
+\r
+               tableLeft.put(leftValue, rightValue);\r
+               tableRight.put(rightValue, leftValue);\r
+       }\r
+\r
+       public boolean isEmpty() {\r
+           return tableLeft.isEmpty();\r
+       }\r
+\r
+    public int size()\r
+    {\r
+        return tableLeft.size();\r
+    }\r
+\r
+       public L getLeft(R rightValue) {\r
+               return tableRight.get(rightValue);\r
+       }\r
+\r
+       public R getRight(L leftValue) {\r
+               return tableLeft.get(leftValue);\r
+       }\r
+\r
+       public R removeWithLeft(L leftValue) {\r
+               R rightValue = tableLeft.remove(leftValue);\r
+               if (rightValue!=null)\r
+                       tableRight.remove(rightValue);\r
+               return rightValue;\r
+       }\r
+\r
+       public L removeWithRight(R rightValue) {\r
+               L leftValue = tableRight.remove(rightValue);\r
+               if (leftValue!=null)\r
+                       tableLeft.remove(leftValue);\r
+               return leftValue;\r
+       }\r
+\r
+       /**\r
+        * Get set of left values\r
+        *\r
+        * @return read-only set\r
+        */\r
+    public Set<L> getLeftSet() {\r
+        return imLeftSet;\r
+    }\r
+\r
+    /**\r
+     * Get set of right values\r
+     *\r
+     * @return read-only set\r
+     */\r
+    public Set<R> getRightSet() {\r
+        return imRightSet;\r
+    }\r
+\r
+    /**\r
+     * Get left-to-right map\r
+     *\r
+     * @return read only map\r
+     */\r
+    public Map<L, R> getLeftToRightMap() {\r
+        return imTableLeft;\r
+    }\r
+\r
+    /**\r
+     * Get right-to-left map\r
+     *\r
+     * @return read only map\r
+     */\r
+    public Map<R, L> getRightToLeftMap() {\r
+        return imTableRight;\r
+    }\r
+\r
+    public void clear() {\r
+        tableLeft.clear();\r
+        tableRight.clear();\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+       int count = 0;\r
+       StringBuilder sb = new StringBuilder();\r
+       sb.append("[");\r
+       for (Entry<L, R> e : tableLeft.entrySet())\r
+       {\r
+               if (count++>0) sb.append(", ");\r
+               sb.append(e.getKey().toString());\r
+               sb.append("=");\r
+               sb.append(e.getValue().toString());\r
+       }\r
+       sb.append("]");\r
+       return sb.toString();\r
+    }\r
+\r
+    @Override\r
+    public LinkedBijectionMap<L, R> clone() {\r
+        return new LinkedBijectionMap<L, R>(this);\r
+    }\r
+}\r