JAL-1925 update source version in license
[jalview.git] / src / jalview / io / vamsas / Sequencemapping.java
index 867b498..07d6141 100644 (file)
-package jalview.io.vamsas;\r
-\r
-import java.util.Vector;\r
-\r
-import jalview.datamodel.AlignedCodonFrame;\r
-import jalview.datamodel.Mapping;\r
-import jalview.datamodel.SequenceI;\r
-import jalview.io.VamsasAppDatastore;\r
-import uk.ac.vamsas.client.Vobject;\r
-import uk.ac.vamsas.objects.core.AlignmentSequence;\r
-import uk.ac.vamsas.objects.core.DataSet;\r
-import uk.ac.vamsas.objects.core.Local;\r
-import uk.ac.vamsas.objects.core.RangeType;\r
-import uk.ac.vamsas.objects.core.Seg;\r
-import uk.ac.vamsas.objects.core.Sequence;\r
-import uk.ac.vamsas.objects.core.SequenceMapping;\r
-import uk.ac.vamsas.objects.core.SequenceType;\r
-\r
-public class Sequencemapping extends Rangetype\r
-{\r
-  public Sequencemapping(VamsasAppDatastore datastore, SequenceMapping sequenceMapping)\r
-  {\r
-    super(datastore);\r
-    Object mjvmapping = getvObj2jv(sequenceMapping);\r
-    if (mjvmapping==null)\r
-    {\r
-      add(sequenceMapping);\r
-    } else {\r
-      if (sequenceMapping.isUpdated())\r
-      {\r
-        update((jalview.datamodel.Mapping) mjvmapping, sequenceMapping);\r
-      }\r
-    }\r
-  }\r
-  /**\r
-   * create or update a vamsas sequence mapping corresponding to a jalview\r
-   * Mapping between two dataset sequences\r
-   * \r
-   * @param datastore\r
-   * @param mjvmapping\r
-   * @param from\r
-   * @param ds\r
-   */\r
-  public Sequencemapping(VamsasAppDatastore datastore, jalview.datamodel.Mapping mjvmapping, uk.ac.vamsas.objects.core.SequenceType from, uk.ac.vamsas.objects.core.DataSet ds)\r
-  {\r
-    super(datastore);\r
-    SequenceMapping sequenceMapping = (SequenceMapping) getjv2vObj(mjvmapping);\r
-    if (sequenceMapping==null)\r
-    {\r
-      add(mjvmapping, from, ds);\r
-    } else {\r
-      if (from!=null && sequenceMapping.getLoc()!=from)\r
-      {\r
-        jalview.bin.Cache.log.warn("Probable IMPLEMENTATION ERROR: "+from+" doesn't match the local mapping sequence.");\r
-      }\r
-      if (ds!=null && sequenceMapping.getV_parent()!=ds)\r
-      {\r
-        jalview.bin.Cache.log.warn("Probable IMPLEMENTATION ERROR: "+ds+" doesn't match the parent of the bound sequence mapping object.");\r
-      }\r
-      if (sequenceMapping.isUpdated())\r
-      { \r
-        conflict(mjvmapping, sequenceMapping);\r
-      } else {\r
-        update(mjvmapping, sequenceMapping);\r
-      }\r
-    }\r
-  }\r
-  private void conflict(Mapping mjvmapping, SequenceMapping sequenceMapping)\r
-  {\r
-    // TODO Auto-generated method stub\r
-\r
-  }\r
-  private void add(Mapping mjvmapping, uk.ac.vamsas.objects.core.SequenceType from, DataSet ds)\r
-  {\r
-    SequenceI jvto = mjvmapping.getTo();\r
-    while (jvto.getDatasetSequence()!=null)\r
-    {\r
-      jvto = jvto.getDatasetSequence();\r
-    }\r
-    SequenceType to = (SequenceType) getjv2vObj(jvto);\r
-    if (to==null)\r
-    {\r
-      jalview.bin.Cache.log.warn("NONFATAL - do a second update: Ignoring Forward Reference to seuqence not yet bound to vamsas seuqence object");\r
-      return;\r
-    } \r
-    SequenceMapping sequenceMapping = new SequenceMapping();\r
-    sequenceMapping.setLoc(from);\r
-    sequenceMapping.setMap(to);\r
-    boolean dnaToProt=false,sense=false;\r
-    // ensure that we create a mapping with the correct sense\r
-    if (((Sequence) sequenceMapping.getLoc())\r
-            .getDictionary()\r
-            .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA))\r
-    {\r
-      if (((Sequence) sequenceMapping.getMap())\r
-              .getDictionary()\r
-              .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_AA))\r
-      {\r
-        dnaToProt=true;\r
-        sense=true;\r
-      } \r
-    } else {\r
-      if (((Sequence) sequenceMapping.getMap())\r
-              .getDictionary()\r
-              .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA))\r
-      {\r
-        dnaToProt=true;\r
-        sense=false;\r
-      } \r
-    }\r
-\r
-    if (!dnaToProt)\r
-    {\r
-      jalview.bin.Cache.log.warn("Ignoring Mapping - don't support protein to protein mapping in vamsas document yet.");\r
-      return;\r
-    }\r
-    if (ds==null)\r
-    {\r
-      // locate dataset for storage of SequenceMapping\r
-      if (sense)\r
-      {\r
-        ds = (DataSet) ((uk.ac.vamsas.client.Vobject) sequenceMapping.getLoc()).getV_parent();\r
-      } else {\r
-        ds = (DataSet) ((uk.ac.vamsas.client.Vobject) sequenceMapping.getMap()).getV_parent();\r
-      } \r
-    }\r
-    if (sense)\r
-    {\r
-      this.initMapType(sequenceMapping, mjvmapping.getMap(), true);\r
-    } else {\r
-      this.initMapType(sequenceMapping, mjvmapping.getMap().getInverse(), true);\r
-    }\r
-    ds.addSequenceMapping(sequenceMapping);\r
-    sequenceMapping.setProvenance(this.dummyProvenance("user defined coding region translation")); // TODO:\r
-    // correctly\r
-    // construct\r
-    // provenance\r
-    // based\r
-    // on\r
-    // source\r
-    // of\r
-    // mapping\r
-    bindjvvobj(mjvmapping, sequenceMapping);\r
-\r
-    jalview.bin.Cache.log.debug("Successfully created mapping "+sequenceMapping.getVorbaId());\r
-  }\r
-  private void update(jalview.datamodel.Mapping mjvmapping, SequenceMapping sequenceMapping)\r
-  {\r
-    jalview.bin.Cache.log.error("Not implemented: Jalview Update Mapping"); \r
-  }\r
-  /**\r
-   * limitations: Currently, jalview only deals with mappings between dataset\r
-   * sequences, and even then, only between those that map from DNA to Protein.\r
-   * \r
-   * @param sequenceMapping\r
-   */\r
-  private void add(SequenceMapping sequenceMapping)\r
-  {\r
-    Object mobj;\r
-    SequenceI from=null,to=null;\r
-    boolean dnaToProt=false,sense=false;\r
-    Sequence sdloc=null, sdmap=null;\r
-    if (sequenceMapping.getLoc() instanceof AlignmentSequence)\r
-    {\r
-      sdloc = (Sequence) ((AlignmentSequence) sequenceMapping.getLoc()).getRefid();\r
-    } else {\r
-      sdloc = ((Sequence) sequenceMapping.getLoc());\r
-    }\r
-    if (sequenceMapping.getMap() instanceof AlignmentSequence)\r
-    {\r
-      sdmap = (Sequence) ((AlignmentSequence) sequenceMapping.getMap()).getRefid();\r
-    } else {\r
-      sdmap = ((Sequence) sequenceMapping.getMap());\r
-    }\r
-    if (sdloc==null || sdmap == null)\r
-    {\r
-      jalview.bin.Cache.log.info("Ignoring non sequence-sequence mapping");\r
-      return;\r
-    }\r
-    mobj = this.getvObj2jv((Vobject) sdloc);\r
-    if (mobj instanceof SequenceI)\r
-    {\r
-      from = (SequenceI) mobj;\r
-    }\r
-    mobj = this.getvObj2jv((Vobject) sdmap);\r
-    if (mobj instanceof SequenceI)\r
-    {\r
-      to = (SequenceI) mobj;\r
-    }\r
-    if (from == null || to == null)\r
-    {\r
-\r
-      jalview.bin.Cache.log.error("Probable Vamsas implementation error : unbound dataset sequences involved in a mapping are being parsed!");\r
-      return;\r
-    } \r
-    if (sdloc.getDictionary()\r
-            .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA))\r
-    {\r
-      if (sdmap.getDictionary()\r
-              .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_AA))\r
-      {\r
-        dnaToProt=true;\r
-        sense=true;\r
-      } \r
-      // else {\r
-\r
-      // }\r
-    } else {\r
-      if (sdmap.getDictionary()\r
-              .equals(uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA))\r
-      {\r
-        dnaToProt=true;\r
-        sense=false;\r
-      } \r
-    }\r
-    // create mapping storage object and make each dataset alignment reference\r
-    // it.\r
-    jalview.datamodel.AlignmentI dsLoc = (jalview.datamodel.AlignmentI) getvObj2jv(sdloc.getV_parent());\r
-    jalview.datamodel.AlignmentI dsMap = (jalview.datamodel.AlignmentI) getvObj2jv(sdmap.getV_parent());\r
-    AlignedCodonFrame afc = new AlignedCodonFrame(0);\r
-\r
-    if (dsLoc!=null && dsLoc!=dsMap)\r
-    {\r
-      dsLoc.addCodonFrame(afc);\r
-    }\r
-    if (dsMap!=null)\r
-    {\r
-      dsMap.addCodonFrame(afc);\r
-    }\r
-    // create and add the new mapping to (each) dataset's codonFrame\r
-\r
-    jalview.util.MapList mapping = null; \r
-    if (!sense)\r
-    {\r
-      mapping = this.parsemapType(sequenceMapping, 1, 3); // invert sense\r
-      mapping = new jalview.util.MapList(mapping.getToRanges(), mapping.getFromRanges(), mapping.getToRatio(), mapping.getFromRatio());\r
-      afc.addMap(to, from, mapping);\r
-    } else {\r
-      mapping = this.parsemapType(sequenceMapping, 3, 1); // correct sense\r
-      afc.addMap(from, to, mapping);\r
-    }\r
-    bindjvvobj(mapping, sequenceMapping);\r
-    jalview.structure.StructureSelectionManager.getStructureSelectionManager().addMappings(new AlignedCodonFrame[] { afc });\r
-  }\r
-}
\ No newline at end of file
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.9.0b2)
+ * Copyright (C) 2015 The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.io.vamsas;
+
+import jalview.datamodel.AlignedCodonFrame;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Mapping;
+import jalview.datamodel.SequenceI;
+import jalview.gui.Desktop;
+import jalview.io.VamsasAppDatastore;
+
+import java.util.Vector;
+
+import uk.ac.vamsas.objects.core.AlignmentSequence;
+import uk.ac.vamsas.objects.core.DataSet;
+import uk.ac.vamsas.objects.core.Sequence;
+import uk.ac.vamsas.objects.core.SequenceMapping;
+import uk.ac.vamsas.objects.core.SequenceType;
+
+/**
+ * binds a vamsas sequence mapping object from the vamsas document to a maplist
+ * object associated with a mapping in the Jalview model. We use the maplist
+ * object because these are referred to both in the Mapping object associated
+ * with a jalview.datamodel.DBRefEntry and in the array of
+ * jalview.datamodel.AlCodonFrame objects that Jalview uses to propagate
+ * sequence mapping position highlighting across the views.
+ * 
+ * @author JimP
+ * 
+ */
+public class Sequencemapping extends Rangetype
+{
+  public Sequencemapping(VamsasAppDatastore datastore,
+          SequenceMapping sequenceMapping)
+  {
+    super(datastore, sequenceMapping, jalview.util.MapList.class);
+    doJvUpdate();
+  }
+
+  private SequenceType from;
+
+  private DataSet ds;
+
+  private Mapping mjvmapping;
+
+  /**
+   * create or update a vamsas sequence mapping corresponding to a jalview
+   * Mapping between two dataset sequences
+   * 
+   * @param datastore
+   * @param mjvmapping
+   * @param from
+   * @param ds
+   */
+  public Sequencemapping(VamsasAppDatastore datastore,
+          jalview.datamodel.Mapping mjvmapping,
+          uk.ac.vamsas.objects.core.SequenceType from,
+          uk.ac.vamsas.objects.core.DataSet ds)
+  {
+    super(datastore, mjvmapping.getMap(), SequenceMapping.class);
+    this.from = from;
+    this.ds = ds;
+    this.mjvmapping = mjvmapping;
+    validate();
+    doSync();
+  }
+
+  /**
+   * local check that extant mapping context is valid
+   */
+  public void validate()
+  {
+
+    SequenceMapping sequenceMapping = (SequenceMapping) vobj;
+    if (sequenceMapping == null)
+    {
+      return;
+    }
+    if (from != null && sequenceMapping.getLoc() != from)
+    {
+      jalview.bin.Cache.log.warn("Probable IMPLEMENTATION ERROR: " + from
+              + " doesn't match the local mapping sequence.");
+    }
+    if (ds != null && sequenceMapping.is__stored_in_document()
+            && sequenceMapping.getV_parent() != ds)
+    {
+      jalview.bin.Cache.log
+              .warn("Probable IMPLEMENTATION ERROR: "
+                      + ds
+                      + " doesn't match the parent of the bound sequence mapping object.");
+    }
+  }
+
+  public void addToDocument()
+  {
+    add(mjvmapping, from, ds);
+  }
+
+  public void addFromDocument()
+  {
+    add((SequenceMapping) vobj);
+  }
+
+  public void conflict()
+  {
+    conflict(mjvmapping, (SequenceMapping) vobj);
+
+  }
+
+  public void updateToDoc()
+  {
+    update(mjvmapping, (SequenceMapping) vobj);
+  }
+
+  public void updateFromDoc()
+  {
+    update((SequenceMapping) vobj, (jalview.datamodel.Mapping) jvobj);
+  }
+
+  private void conflict(Mapping mjvmapping, SequenceMapping sequenceMapping)
+  {
+    System.err.println("Conflict in update of sequenceMapping "
+            + sequenceMapping.getVorbaId());
+  }
+
+  private void add(Mapping mjvmapping,
+          uk.ac.vamsas.objects.core.SequenceType from, DataSet ds)
+  {
+    SequenceI jvto = mjvmapping.getTo();
+    while (jvto.getDatasetSequence() != null)
+    {
+      jvto = jvto.getDatasetSequence();
+    }
+    SequenceType to = (SequenceType) getjv2vObj(jvto);
+    if (to == null)
+    {
+      jalview.bin.Cache.log
+              .warn("FIXME NONFATAL - do a second update: Ignoring Forward Reference to seuqence not yet bound to vamsas seuqence object");
+      return;
+    }
+    SequenceMapping sequenceMapping = new SequenceMapping();
+    sequenceMapping.setLoc(from);
+    sequenceMapping.setMap(to);
+    boolean dnaToProt = false, sense = false;
+    // ensure that we create a mapping with the correct sense
+    if (((Sequence) sequenceMapping.getLoc()).getDictionary().equals(
+            uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA))
+    {
+      if (((Sequence) sequenceMapping.getMap()).getDictionary().equals(
+              uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_AA))
+      {
+        dnaToProt = true;
+        sense = true;
+      }
+    }
+    else
+    {
+      if (((Sequence) sequenceMapping.getMap()).getDictionary().equals(
+              uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA))
+      {
+        dnaToProt = true;
+        sense = false;
+      }
+    }
+
+    if (!dnaToProt)
+    {
+      jalview.bin.Cache.log
+              .warn("Ignoring Mapping - don't support protein to protein mapping in vamsas document yet.");
+      return;
+    }
+    if (ds == null)
+    {
+      // locate dataset for storage of SequenceMapping
+      if (sense)
+      {
+        ds = (DataSet) ((uk.ac.vamsas.client.Vobject) sequenceMapping
+                .getLoc()).getV_parent();
+      }
+      else
+      {
+        ds = (DataSet) ((uk.ac.vamsas.client.Vobject) sequenceMapping
+                .getMap()).getV_parent();
+      }
+    }
+    if (sense)
+    {
+      this.initMapType(sequenceMapping, mjvmapping.getMap(), true);
+    }
+    else
+    {
+      this.initMapType(sequenceMapping, mjvmapping.getMap().getInverse(),
+              true);
+    }
+    ds.addSequenceMapping(sequenceMapping);
+    sequenceMapping.setProvenance(this
+            .dummyProvenance("user defined coding region translation")); // TODO:
+    // correctly
+    // construct
+    // provenance
+    // based
+    // on
+    // source
+    // of
+    // mapping
+    bindjvvobj(mjvmapping.getMap(), sequenceMapping);
+
+    jalview.bin.Cache.log.debug("Successfully created mapping "
+            + sequenceMapping.getVorbaId());
+  }
+
+  // private void update(jalview.util.MapList mjvmapping,
+  // SequenceMapping sequenceMapping)
+  {
+    jalview.bin.Cache.log
+            .error("Not implemented: Jalview Update Alcodon Mapping:TODO!");
+  }
+
+  private void update(SequenceMapping sequenceMapping,
+          jalview.datamodel.Mapping mjvmapping)
+  {
+    jalview.bin.Cache.log
+            .error("Not implemented: Update DBRef Mapping from Jalview");
+  }
+
+  private void update(jalview.datamodel.Mapping mjvmapping,
+          SequenceMapping sequenceMapping)
+  {
+    jalview.bin.Cache.log
+            .error("Not implemented: Jalview Update Sequence DBRef Mapping");
+  }
+
+  /**
+   * bind a SequenceMapping to a live AlCodonFrame element limitations:
+   * Currently, jalview only deals with mappings between dataset sequences, and
+   * even then, only between those that map from DNA to Protein.
+   * 
+   * @param sequenceMapping
+   */
+  private void add(SequenceMapping sequenceMapping)
+  {
+    Object mobj;
+    SequenceI from = null, to = null;
+    boolean dnaToProt = false, sense = false;
+    Sequence sdloc = null, sdmap = null;
+    if (sequenceMapping.getLoc() instanceof AlignmentSequence)
+    {
+      sdloc = (Sequence) ((AlignmentSequence) sequenceMapping.getLoc())
+              .getRefid();
+    }
+    else
+    {
+      sdloc = ((Sequence) sequenceMapping.getLoc());
+    }
+    if (sequenceMapping.getMap() instanceof AlignmentSequence)
+    {
+      sdmap = (Sequence) ((AlignmentSequence) sequenceMapping.getMap())
+              .getRefid();
+    }
+    else
+    {
+      sdmap = ((Sequence) sequenceMapping.getMap());
+    }
+    if (sdloc == null || sdmap == null)
+    {
+      jalview.bin.Cache.log.info("Ignoring non sequence-sequence mapping");
+      return;
+    }
+    mobj = this.getvObj2jv(sdloc);
+    if (mobj instanceof SequenceI)
+    {
+      from = (SequenceI) mobj;
+    }
+    mobj = this.getvObj2jv(sdmap);
+    if (mobj instanceof SequenceI)
+    {
+      to = (SequenceI) mobj;
+    }
+    if (from == null || to == null)
+    {
+
+      jalview.bin.Cache.log
+              .error("Probable Vamsas implementation error : unbound dataset sequences involved in a mapping are being parsed!");
+      return;
+    }
+
+    if (sdloc.getDictionary().equals(
+            uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA))
+    {
+      if (sdmap.getDictionary().equals(
+              uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_AA))
+      {
+        dnaToProt = true;
+        sense = true;
+      }
+      // else {
+
+      // }
+    }
+    else
+    {
+      if (sdmap.getDictionary().equals(
+              uk.ac.vamsas.objects.utils.SymbolDictionary.STANDARD_NA))
+      {
+        dnaToProt = true;
+        sense = false;
+      }
+    }
+    // create mapping storage object and make each dataset alignment reference
+    // it.
+    AlignmentI dsLoc = (AlignmentI) getvObj2jv(sdloc.getV_parent());
+    AlignmentI dsMap = (AlignmentI) getvObj2jv(sdmap.getV_parent());
+    AlignedCodonFrame acf = new AlignedCodonFrame();
+
+    if (dsLoc != null && dsLoc != dsMap)
+    {
+      dsLoc.addCodonFrame(acf);
+    }
+    if (dsMap != null)
+    {
+      dsMap.addCodonFrame(acf);
+    }
+    // create and add the new mapping to (each) dataset's codonFrame
+
+    jalview.util.MapList mapping = null;
+    if (dnaToProt)
+    {
+      if (!sense)
+      {
+        mapping = this.parsemapType(sequenceMapping, 1, 3); // invert sense
+        mapping = new jalview.util.MapList(mapping.getToRanges(),
+                mapping.getFromRanges(), mapping.getToRatio(),
+                mapping.getFromRatio());
+        acf.addMap(to, from, mapping);
+      }
+      else
+      {
+        mapping = this.parsemapType(sequenceMapping, 3, 1); // correct sense
+        acf.addMap(from, to, mapping);
+      }
+    }
+    else
+    {
+      mapping = this.parsemapType(sequenceMapping, 1, 1); // correct sense
+      acf.addMap(from, to, mapping);
+    }
+    bindjvvobj(mapping, sequenceMapping);
+    jalview.structure.StructureSelectionManager
+            .getStructureSelectionManager(Desktop.instance)
+            .registerMapping(acf);
+    // Try to link up any conjugate database references in the two sequences
+    // matchConjugateDBRefs(from, to, mapping);
+    // Try to propagate any dbrefs across this mapping.
+
+  }
+
+  /**
+   * Complete any 'to' references in jalview.datamodel.Mapping objects
+   * associated with conjugate DBRefEntry under given mapping
+   * 
+   * @param from
+   *          sequence corresponding to from reference for sequence mapping
+   * @param to
+   *          sequence correspondeing to to reference for sequence mapping
+   * @param smap
+   *          maplist parsed in same sense as from and to
+   */
+  private void matchConjugateDBRefs(SequenceI from, SequenceI to,
+          jalview.util.MapList smap)
+  {
+    if (from.getDBRef() == null && to.getDBRef() == null)
+    {
+      if (jalview.bin.Cache.log.isDebugEnabled())
+      {
+        jalview.bin.Cache.log.debug("Not matching conjugate refs for "
+                + from.getName() + " and " + to.getName());
+      }
+      return;
+    }
+    if (jalview.bin.Cache.log.isDebugEnabled())
+    {
+      jalview.bin.Cache.log.debug("Matching conjugate refs for "
+              + from.getName() + " and " + to.getName());
+    }
+    jalview.datamodel.DBRefEntry[] fdb = from.getDBRef();
+    jalview.datamodel.DBRefEntry[] tdb = new jalview.datamodel.DBRefEntry[to
+            .getDBRef().length];
+    int tdblen = to.getDBRef().length;
+    System.arraycopy(to.getDBRef(), 0, tdb, 0, tdblen);
+    Vector matched = new Vector();
+    jalview.util.MapList smapI = smap.getInverse();
+    for (int f = 0; f < fdb.length; f++)
+    {
+      jalview.datamodel.DBRefEntry fe = fdb[f];
+      jalview.datamodel.Mapping fmp = fe.getMap();
+      boolean fmpnnl = fmp != null;
+      // if (fmpnnl && fmp.getTo()!=null)
+      // {
+      // jalview.bin.Cache.log.debug("Not overwriting existing To reference in
+      // "+fe);
+      // continue;
+      // }
+      // smap from maps from fe.local to fe.map
+      boolean smapfromlocal2fe = (fmpnnl) ? smap.equals(fmp.getMap())
+              : false;
+      // smap from maps from fe.map to fe.local.
+      boolean smapfromfemap2local = (fmpnnl) ? smapI.equals(fmp.getMap())
+              : false;
+      for (int t = 0; t < tdblen; t++)
+      {
+        jalview.datamodel.DBRefEntry te = tdb[t];
+        if (te != null)
+        {
+          if (fe.getSource().equals(te.getSource())
+                  && fe.getAccessionId().equals(te.getAccessionId()))
+          {
+            jalview.datamodel.Mapping tmp = te.getMap();
+            boolean tmpnnl = tmp != null;
+            if (tmpnnl && tmp.getTo() != null)
+            {
+
+            }
+            // smap to maps from te.local to te.map
+            boolean smaptolocal2tm = (tmpnnl) ? smap.equals(tmp.getMap())
+                    : false;
+            // smap to maps from te.map to te.local
+            boolean smaptotemap2local = (tmpnnl) ? smapI.equals(fmp
+                    .getMap()) : false;
+            if (smapfromlocal2fe && smaptotemap2local)
+            {
+              // smap implies mapping from to to from
+              fmp.setTo(to);
+              tmp.setTo(from);
+            }
+            else if (smapfromfemap2local && smaptolocal2tm)
+            {
+              fmp.setTo(to);
+            }
+          }
+
+        }
+      }
+    }
+  }
+}