+ seqs.add(curDs);
+ // iterate over database references, making sure we add forward referenced
+ // sequences
+ if (curDs.getDBRefs() != null)
+ {
+ for (DBRefEntry dbr : curDs.getDBRefs())
+ {
+ if (dbr.getMap() != null && dbr.getMap().getTo() != null)
+ {
+ if (dbr.getMap().getTo() == alignedSeq)
+ {
+ /*
+ * update mapping to be to the newly created dataset sequence
+ */
+ dbr.getMap().setTo(currentSeq);
+ }
+ if (dbr.getMap().getTo().getDatasetSequence() != null)
+ {
+ throw new Error(
+ "Implementation error: Map.getTo() for dbref " + dbr
+ + " from " + curDs.getName()
+ + " is not a dataset sequence.");
+ }
+ // we recurse to add all forward references to dataset sequences via
+ // DBRefs/etc
+ toProcess.add(dbr.getMap().getTo());
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Creates a new dataset for this alignment. Can only be done once - if
+ * dataset is not null this will not be performed.
+ */
+ public void createDatasetAlignment()
+ {
+ if (dataset != null)
+ {
+ return;
+ }
+ // try to avoid using SequenceI.equals at this stage, it will be expensive
+ Set<SequenceI> seqs = new LinkedIdentityHashSet<SequenceI>();
+
+ for (int i = 0; i < getHeight(); i++)
+ {
+ SequenceI currentSeq = getSequenceAt(i);
+ resolveAndAddDatasetSeq(currentSeq, seqs, true);
+ }
+
+ // verify all mappings are in dataset
+ for (AlignedCodonFrame cf : codonFrameList)
+ {
+ for (SequenceToSequenceMapping ssm : cf.getMappings())
+ {
+ if (!seqs.contains(ssm.getFromSeq()))
+ {
+ resolveAndAddDatasetSeq(ssm.getFromSeq(), seqs, false);
+ }
+ if (!seqs.contains(ssm.getMapping().getTo()))
+ {
+ resolveAndAddDatasetSeq(ssm.getMapping().getTo(), seqs, false);
+ }
+ }
+ }
+ // finally construct dataset
+ dataset = new Alignment(seqs.toArray(new SequenceI[seqs.size()]));
+ // move mappings to the dataset alignment
+ dataset.codonFrameList = this.codonFrameList;
+ this.codonFrameList = null;
+ }
+
+ /**
+ * reference count for number of alignments referencing this one.
+ */
+ int alignmentRefs = 0;
+
+ /**
+ * increase reference count to this alignment.
+ */
+ private void addAlignmentRef()
+ {
+ alignmentRefs++;
+ }
+
+ @Override
+ public Alignment getDataset()
+ {
+ return dataset;
+ }
+
+ @Override
+ public boolean padGaps()
+ {
+ boolean modified = false;
+
+ // Remove excess gaps from the end of alignment
+ int maxLength = -1;
+
+ SequenceI current;
+ for (int i = 0; i < sequences.size(); i++)
+ {
+ current = getSequenceAt(i);
+ for (int j = current.getLength(); j > maxLength; j--)