diff --git a/src/apps/rednatco/api.ts b/src/apps/rednatco/api.ts
index 1010c70981aa32435d3a3529e7fcb3d70dc1bec5..073937f047dab5169e034a1045ddad216d98f5e3 100644
--- a/src/apps/rednatco/api.ts
+++ b/src/apps/rednatco/api.ts
@@ -1,6 +1,19 @@
 import { Filters } from './filters';
 
 export namespace ReDNATCOMspApi {
+    export namespace Payloads {
+        export type StepSelection = {
+            name: string;
+            reference?: {
+                NtC: string,
+                color: number,
+            };
+        }
+        function StepSelection(name: string, reference?: StepSelection['reference']): StepSelection {
+            return { name, reference };
+        }
+    }
+
     export namespace Commands {
         export type Type = 'deselect-step'|'filter'|'redraw'|'select-step'|'switch-model';
 
@@ -19,21 +32,12 @@ export namespace ReDNATCOMspApi {
 
         export type SelectStep = {
             type: 'select-step';
-            stepName: string;
-            prevStepName: string|undefined;
-            nextStepName: string|undefined;
-            referenceNtC: string;
-            references: ('sel'|'prev'|'next')[];
-        }
-        export function SelectStep(stepName: string, prevStepName: string|undefined, nextStepName: string|undefined, referenceNtC = '', references = ['sel', 'prev', 'next']): SelectStep {
-            return {
-                type: 'select-step',
-                stepName,
-                prevStepName,
-                nextStepName,
-                referenceNtC,
-                references: references as ('sel'|'prev'|'next')[],
-            };
+            step: Payloads.StepSelection
+            prev?: Payloads.StepSelection;
+            next?: Payloads.StepSelection
+        }
+        export function SelectStep(step: Payloads.StepSelection, prev: Payloads.StepSelection|undefined, next: Payloads.StepSelection|undefined): SelectStep {
+            return { type: 'select-step', step, prev, next };
         }
 
         export type SwitchModel = { type: 'switch-model', model: number };
@@ -71,9 +75,9 @@ export namespace ReDNATCOMspApi {
             return { type: 'step-requested', name };
         }
 
-        export type StepSelected = { type: 'step-selected', success: boolean, name: string, rmsd?: number }
-        export function StepSelectedOk(name: string, rmsd?: number): StepSelected {
-            return { type: 'step-selected', success: true, name, rmsd };
+        export type StepSelected = { type: 'step-selected', success: boolean, name: string }
+        export function StepSelectedOk(name: string): StepSelected {
+            return { type: 'step-selected', success: true, name };
         }
         export function StepSelectedFail(): StepSelected {
             return { type: 'step-selected', success: false, name: '' };
@@ -105,9 +109,9 @@ export namespace ReDNATCOMspApi {
             return { type: 'current-model-number', num };
         }
 
-        export type SelectedStep = { type: 'selected-step', name: string, rmsd?: number }
-        export function SelectedStep(name: string, rmsd?: number): SelectedStep {
-            return { type: 'selected-step', name, rmsd };
+        export type SelectedStep = { type: 'selected-step', selected?: Payloads.StepSelection }
+        export function SelectedStep(selected?: Payloads.StepSelection): SelectedStep {
+            return { type: 'selected-step', selected };
         }
     }
     export type Response = Queries.CurrentFilter|Queries.CurrentModelNumber|Queries.SelectedStep;
diff --git a/src/apps/rednatco/index.tsx b/src/apps/rednatco/index.tsx
index 37342bbd618a181a8d252cc4ffbe06a72f5a391b..9216dc3c1984cabfc8764e8be188f101b547690d 100644
--- a/src/apps/rednatco/index.tsx
+++ b/src/apps/rednatco/index.tsx
@@ -9,6 +9,7 @@ import { ColorPicker } from './color-picker';
 import { CollapsibleVertical, PushButton, ToggleButton } from './controls';
 import { luminance } from './util';
 import { Color } from '../../mol-util/color';
+import { assertUnreachable } from '../../mol-util/type-helpers';
 import './index.html';
 
 const ConformersByClass = {
@@ -77,7 +78,7 @@ export class ReDNATCOMsp extends React.Component<ReDNATCOMsp.Props, State> {
     private currentFilter: Filters.All = Filters.Empty();
     private presentConformers: string[] = [];
     private viewer: ReDNATCOMspViewer|undefined = undefined;
-    private selectedStep: { name: string, rmsd?: number }|undefined;
+    private selectedStep: Api.Payloads.StepSelection|undefined = undefined;
 
     constructor(props: ReDNATCOMsp.Props) {
         super(props);
@@ -148,19 +149,18 @@ export class ReDNATCOMsp extends React.Component<ReDNATCOMsp.Props, State> {
         this.setState({ ...this.state, display });
     }
 
-    apiQuery(type: Api.Queries.Type): Api.Response {
+    apiQuery(type: Api.Queries.Type) {
         if (type === 'current-filter') {
             return Api.Queries.CurrentFilter(this.currentFilter);
         } else if (type === 'current-model-number') {
             return Api.Queries.CurrentModelNumber(this.viewer!.currentModelNumber());
         } else if (type === 'selected-step') {
             if (this.selectedStep)
-                return Api.Queries.SelectedStep(this.selectedStep.name, this.selectedStep.rmsd);
-            return Api.Queries.SelectedStep('');
+                return Api.Queries.SelectedStep(this.selectedStep);
+            return Api.Queries.SelectedStep();
         }
 
-        // TODO: This cannot happen - figure out how to assert on this
-        return Api.Queries.SelectedStep('');
+        assertUnreachable(type);
     }
 
     async command(cmd: Api.Command) {
@@ -181,16 +181,16 @@ export class ReDNATCOMsp extends React.Component<ReDNATCOMsp.Props, State> {
             this.currentFilter = cmd.filter;
             ReDNATCOMspApi.event(Api.Events.FilterApplied());
         } else if (cmd.type === 'select-step') {
-            const ret = await this.viewer.actionSelectStep(cmd.stepName, cmd.prevStepName, cmd.nextStepName, cmd.referenceNtC, cmd.references, this.state.display);
+            const ret = await this.viewer.actionSelectStep(cmd.step, cmd.prev, cmd.next, this.state.display);
             if (!ret) {
                 ReDNATCOMspApi.event(Api.Events.StepSelectedFail());
                 return;
             }
 
             this.viewer.focusOnSelectedStep();
-            this.selectedStep = { name: cmd.stepName, rmsd: ret.rmsd };
+            this.selectedStep = cmd.step;
 
-            ReDNATCOMspApi.event(Api.Events.StepSelectedOk(this.selectedStep.name, this.selectedStep.rmsd));
+            ReDNATCOMspApi.event(Api.Events.StepSelectedOk(this.selectedStep.name));
         } else if (cmd.type === 'switch-model') {
             if (cmd.model < 1 || cmd.model > this.viewer.getModelCount())
                 return;
diff --git a/src/apps/rednatco/reference-conformers.ts b/src/apps/rednatco/reference-conformers.ts
index 32505c6c31665c77bfc5ddc94f12a261a0c422fc..9de0cdcb2dd2a36a4ea24bb924ecf0bdb607ce25 100644
--- a/src/apps/rednatco/reference-conformers.ts
+++ b/src/apps/rednatco/reference-conformers.ts
@@ -1,6 +1,6 @@
 /* eslint-disable array-bracket-spacing, no-multi-spaces, indent */
 
-export type Ring = 'purine'|'pyrimidine';
+export type Ring = 'purine'|'pyrimidine'|'PSU';
 
 export const ReferenceCompounds: Record<string, [string, string]> = {
     AA00: [ 'A',  'G'],
@@ -102,7 +102,7 @@ export const ReferenceCompounds: Record<string, [string, string]> = {
 };
 export type ReferenceCompounds = typeof ReferenceCompounds;
 
-export const CompoundRings: Record<string, Ring> = {
+export const BaseAtomsKinds: Record<string, Ring> = {
     '0AD': 'purine',
     '0AV': 'purine',
     '0SP': 'purine',
@@ -427,14 +427,23 @@ export const CompoundRings: Record<string, Ring> = {
       'U': 'pyrimidine',
     'UMP': 'pyrimidine',
     '2DT': 'pyrimidine',
-    'CFZ': 'pyrimidine'
+    'CFZ': 'pyrimidine',
+
+    'PSU': 'PSU'
 };
-export type CompoundRings = typeof CompoundRings;
 
 export const BackboneAtoms = {
     first: ["C5'", "C4'", "O4'", "C3'", "O3'", "C1'"],
     /* eslint-disable @typescript-eslint/quotes */
     second: ["P", "O5'", "C5'", "C4'", "O4'", "C3'", "O3'", "C1'"],
+};
+
+export const BaseAtoms: Record<keyof typeof BaseAtomsKinds, string[]> = {
     purine: ['N9', 'C4'],
     pyrimidine: ['N1', 'C2'],
+    PSU: ['C5', 'C4'],
 };
+
+export function referenceAtoms(compId: keyof typeof BaseAtomsKinds, order: 'first'|'second') {
+    return [...BackboneAtoms[order], ...BaseAtoms[compId]];
+}
diff --git a/src/apps/rednatco/traverse.ts b/src/apps/rednatco/traverse.ts
index 913b679694f8c8affc7d5a751c056ca9e0aa3eb3..547a81d758deed809eba5d53e4d5b2f27c99e7c5 100644
--- a/src/apps/rednatco/traverse.ts
+++ b/src/apps/rednatco/traverse.ts
@@ -1,7 +1,8 @@
 import { Segmentation } from '../../mol-data/int';
 import { OrderedSet } from '../../mol-data/int/ordered-set';
-import { EmptyLoci, Loci } from '../../mol-model/loci';
+import { EmptyLoci } from '../../mol-model/loci';
 import { ResidueIndex, Structure, StructureElement, StructureProperties, Unit } from '../../mol-model/structure';
+import { structureUnion } from '../../mol-model/structure/query/utils/structure-set';
 import { Location } from '../../mol-model/structure/structure/element/location';
 
 export namespace Traverse {
@@ -20,9 +21,12 @@ export namespace Traverse {
         return altIds;
     }
 
-    export function findResidue(asymId: string, seqId: number, altId: string|undefined, loci: StructureElement.Loci, source: 'label'|'auth') {
+    // TODO: We will be able to use a function from DnatcoUtils once it gets upstreamed
+    const _loc = StructureElement.Location.create();
+    export function findResidue(asymId: string, seqId: number, altId: string|undefined, insCode: string, loci: StructureElement.Loci, source: 'label'|'auth') {
+        _loc.structure = loci.structure;
         for (const e of loci.elements) {
-            const loc = Location.create(loci.structure, e.unit);
+            _loc.unit = e.unit;
 
             const getAsymId = source === 'label' ? StructureProperties.chain.label_asym_id : StructureProperties.chain.auth_asym_id;
             const getSeqId = source === 'label' ? StructureProperties.residue.label_seq_id : StructureProperties.residue.auth_seq_id;
@@ -34,18 +38,22 @@ export namespace Traverse {
             const elemIndex = (idx: number) => OrderedSet.getAt(e.unit.elements, idx);
             while (chainIt.hasNext) {
                 const chain = chainIt.move();
-                loc.element = elemIndex(chain.start);
-                const _asymId = getAsymId(loc);
+                _loc.element = elemIndex(chain.start);
+                const _asymId = getAsymId(_loc);
                 if (_asymId !== asymId)
                     continue; // Wrong chain, skip it
 
                 residueIt.setSegment(chain);
                 while (residueIt.hasNext) {
                     const residue = residueIt.move();
-                    loc.element = elemIndex(residue.start);
+                    _loc.element = elemIndex(residue.start);
 
-                    const _seqId = getSeqId(loc);
+                    const _seqId = getSeqId(_loc);
                     if (_seqId === seqId) {
+                        const _insCode = StructureProperties.residue.pdbx_PDB_ins_code(_loc);
+                        if (_insCode !== insCode)
+                            continue;
+
                         if (altId) {
                             const _altIds = residueAltIds(loci.structure, e.unit, residue);
                             if (!_altIds.includes(altId))
@@ -66,36 +74,21 @@ export namespace Traverse {
         return EmptyLoci;
     }
 
-    export function findStep(asymId: string, seqId: number, altId: string|undefined, loci: StructureElement.Loci, source: 'label'|'auth') {
-        const sel = findResidue(asymId, seqId, altId, loci, source);
-        if (sel.kind === 'empty-loci')
-            return sel;
-
-        return Loci.normalize(sel, 'two-residues');
-    }
-
-    export function residue(shift: number, altId: string|undefined, cursor: StructureElement.Loci) {
-        for (const e of cursor.elements) {
-            const entireUnit = cursor.structure.units[e.unit.id];
-            const loc = Location.create(cursor.structure, e.unit);
-
-            loc.element = e.unit.elements[OrderedSet.getAt(e.indices, 0)];
-            const asymId = StructureProperties.chain.label_asym_id(loc);
-            const seqId = StructureProperties.residue.label_seq_id(loc);
-
-            const from = 0 as StructureElement.UnitIndex;
-            const to = entireUnit.elements.length as StructureElement.UnitIndex;
-
-            const loci = findResidue(
-                asymId,
-                seqId + shift,
-                altId,
-                StructureElement.Loci(cursor.structure, [{ unit: entireUnit, indices: OrderedSet.ofBounds(from, to) }]),
-                'label'
-            );
-            if (!Loci.isEmpty(loci))
-                return loci;
-        }
-        return EmptyLoci;
+    export function findStep(
+        asymId: string,
+        seqId1: number, altId1: string|undefined, insCode1: string,
+        seqId2: number, altId2: string|undefined, insCode2: string,
+        loci: StructureElement.Loci, source: 'label'|'auth'
+    ) {
+        const first = findResidue(asymId, seqId1, altId1, insCode1, loci, source);
+        if (first.kind === 'empty-loci')
+            return EmptyLoci;
+
+        const second = findResidue(asymId, seqId2, altId2, insCode2, loci, source);
+        if (second.kind === 'empty-loci')
+            return EmptyLoci;
+
+        const union = structureUnion(loci.structure, [StructureElement.Loci.toStructure(first), StructureElement.Loci.toStructure(second)]);
+        return Structure.toStructureElementLoci(union);
     }
 }
diff --git a/src/apps/rednatco/viewer.ts b/src/apps/rednatco/viewer.ts
index c54638ddf2b211eeefe05d8319605019079eff95..32007e713e99a8af1c5811c31885bc986d1207ee 100644
--- a/src/apps/rednatco/viewer.ts
+++ b/src/apps/rednatco/viewer.ts
@@ -1,5 +1,6 @@
 import * as IDs from './idents';
 import * as RefCfmr from './reference-conformers';
+import { ReDNATCOMspApi as Api } from './api';
 import { ReDNATCOMsp, Display, VisualRepresentations } from './index';
 import { NtCColors } from './colors';
 import { Filters } from './filters';
@@ -57,39 +58,32 @@ const SphereBoundaryHelper = new BoundaryHelper('98');
 type StepInfo = {
     name: string;
     assignedNtC: string;
-    closestNtC: string; // Fallback for cases where assignedNtC is NANT
+    closestNtC: string;
     chain: string;
     resNo1: number;
     resNo2: number;
+    compId1: string;
+    compId2: string;
     altId1?: string;
     altId2?: string;
+    insCode1: string;
+    insCode2: string;
     model: number;
 }
 
-type StepWithStructure = {
-    step: StepInfo;
-    loci: StructureElement.Loci;
-}
-
-function dinucleotideBackbone(loci: StructureElement.Loci, altId1?: string, altId2?: string) {
+function dinucleotideBackbone(loci: StructureElement.Loci) {
     const es = loci.elements[0];
     const loc = Location.create(loci.structure, es.unit, es.unit.elements[OrderedSet.getAt(es.indices, 0)]);
     const len = OrderedSet.size(es.indices);
     const indices = new Array<ElementIndex>();
 
-    const gather = (atoms: string[], start: number, end: number, altId?: string) => {
+    const gather = (atoms: string[], start: number, end: number) => {
         for (const atom of atoms) {
             let idx = start;
             for (; idx < end; idx++) {
                 loc.element = es.unit.elements[OrderedSet.getAt(es.indices, idx)];
                 const _atom = StructureProperties.atom.label_atom_id(loc);
                 if (atom === _atom) {
-                    if (altId) {
-                        const _altId = StructureProperties.atom.label_alt_id(loc);
-                        if (_altId !== '' && _altId !== altId)
-                            continue;
-                    }
-
                     indices.push(loc.element);
                     break;
                 }
@@ -117,23 +111,18 @@ function dinucleotideBackbone(loci: StructureElement.Loci, altId1?: string, altI
     if (secondIdx === -1)
         return [];
 
-    // Gather ElementIndices for backbone atoms of the first  residue
+    // Gather element indices for the first residue
     loc.element = es.unit.elements[OrderedSet.getAt(es.indices, 0)];
-    const ring1 = RefCfmr.CompoundRings[StructureProperties.atom.label_comp_id(loc) as keyof RefCfmr.CompoundRings];
-    if (!ring1)
-        return [];
-
-    const first = RefCfmr.BackboneAtoms.first.concat(RefCfmr.BackboneAtoms[ring1]);
-    if (!gather(first, 0, secondIdx, altId1))
+    const compId1 = StructureProperties.atom.label_comp_id(loc);
+    const atoms1 = RefCfmr.referenceAtoms(compId1.toUpperCase(), 'first');
+    if (!gather(atoms1, 0, secondIdx))
         return [];
 
+    // Gather element indices for the second residue
     loc.element = es.unit.elements[OrderedSet.getAt(es.indices, secondIdx)];
-    const ring2 = RefCfmr.CompoundRings[StructureProperties.atom.label_comp_id(loc) as keyof RefCfmr.CompoundRings];
-    if (!ring2)
-        return [];
-
-    const second = RefCfmr.BackboneAtoms.second.concat(RefCfmr.BackboneAtoms[ring2]);
-    if (!gather(second, secondIdx, len, altId2))
+    const compId2 = StructureProperties.atom.label_comp_id(loc);
+    const atoms2 = RefCfmr.referenceAtoms(compId2.toUpperCase(), 'second');
+    if (!gather(atoms2, secondIdx, len))
         return [];
 
     return indices;
@@ -307,8 +296,8 @@ export class ReDNATCOMspViewer {
         return parent.obj?.type.name === 'Structure' ? parent.obj : undefined;
     }
 
-    private ntcRef(step: StepInfo, where: 'sel'|'prev'|'next') {
-        return rcref(step.assignedNtC === 'NANT' ? step.closestNtC : step.assignedNtC, where);
+    private ntcRef(ntc: string, where: 'sel'|'prev'|'next') {
+        return rcref(ntc, where);
     }
 
     private pyramidsParams(colors: NtCColors.Conformers, visible: Map<string, boolean>, transparent: boolean) {
@@ -400,9 +389,9 @@ export class ReDNATCOMspViewer {
         }
     }
 
-    private superpose(reference: StructureElement.Loci, stru: StructureElement.Loci, altId1?: string, altId2?: string) {
+    private superpose(reference: StructureElement.Loci, stru: StructureElement.Loci) {
         const refElems = dinucleotideBackbone(reference);
-        const struElems = dinucleotideBackbone(stru, altId1, altId2);
+        const struElems = dinucleotideBackbone(stru);
 
         return Superpose.superposition(
             { elements: refElems, conformation: reference.elements[0].unit.conformation },
@@ -439,22 +428,18 @@ export class ReDNATCOMspViewer {
         }
     }
 
-    private toStepWithStructure(name: string, struLoci: StructureElement.Loci): StepWithStructure|undefined {
+    private toStepLoci(name: string, struLoci: StructureElement.Loci) {
         const step = this.stepFromName(name);
         if (!step)
-            return void 0;
+            return EmptyLoci;
 
-        const loci = Traverse.findStep(
+        return Traverse.findStep(
             step.chain,
-            step.resNo1,
-            step.altId1,
+            step.resNo1, step.altId1, step.insCode1,
+            step.resNo2, step.altId2, step.insCode2,
             struLoci,
             'auth'
         );
-        if (loci.kind === 'element-loci')
-            return { step, loci };
-
-        return void 0;
     }
 
     private waterVisuals(color: Color) {
@@ -704,51 +689,47 @@ export class ReDNATCOMspViewer {
             return void 0;
         }
 
-        const _ids = tableStep.getField('id');
-        const _names = tableStep.getField('name');
-        const _chains = tableStep.getField('auth_asym_id_1');
-        const _authSeqId1 = tableStep.getField('auth_seq_id_1');
-        const _authSeqId2 = tableStep.getField('auth_seq_id_2');
-        const _labelAltId1 = tableStep.getField('label_alt_id_1');
-        const _labelAltId2 = tableStep.getField('label_alt_id_2');
-        const _stepIds = tableSum.getField('step_id');
-        const _assignedNtCs = tableSum.getField('assigned_NtC');
-        const _closestNtCs = tableSum.getField('closest_NtC');
-        const _models = tableStep.getField('PDB_model_number');
-        if (!_ids || !_names || !_chains || !_stepIds || !_assignedNtCs || !_closestNtCs || !_labelAltId1 || !_labelAltId2 || !_authSeqId1 || !_authSeqId2 || !_models) {
+        const _ids = tableStep.getField('id')?.toIntArray();
+        const _names = tableStep.getField('name')?.toStringArray();
+        const _chains = tableStep.getField('auth_asym_id_1')?.toStringArray();
+        const _authSeqId1 = tableStep.getField('auth_seq_id_1')?.toIntArray();
+        const _authSeqId2 = tableStep.getField('auth_seq_id_2')?.toIntArray();
+        const _compId1 = tableStep.getField('label_comp_id_1')?.toStringArray();
+        const _compId2 = tableStep.getField('label_comp_id_2')?.toStringArray();
+        const _labelAltId1 = tableStep.getField('label_alt_id_1')?.toStringArray();
+        const _labelAltId2 = tableStep.getField('label_alt_id_2')?.toStringArray();
+        const _PDBinsCode1 = tableStep.getField('PDB_ins_code_1')?.toStringArray();
+        const _PDBinsCode2 = tableStep.getField('PDB_ins_code_2')?.toStringArray();
+        const _stepIds = tableSum.getField('step_id')?.toIntArray();
+        const _assignedNtCs = tableSum.getField('assigned_NtC')?.toStringArray();
+        const _closestNtCs = tableSum.getField('closest_NtC')?.toStringArray();
+        const _models = tableStep.getField('PDB_model_number')?.toIntArray();
+        if (!_ids || !_names || !_chains || !_stepIds || !_assignedNtCs || !_closestNtCs || !_labelAltId1 || !_labelAltId2 || !_authSeqId1 || !_authSeqId2 || !_compId1 || !_compId2 || !_PDBinsCode1 || !_PDBinsCode2 || !_models) {
             console.warn('Expected fields are not present in NtC categories');
             return void 0;
         }
 
-        const ids = _ids.toIntArray();
-        const names = _names.toStringArray();
-        const chains = _chains.toStringArray();
-        const authSeqId1 = _authSeqId1.toIntArray();
-        const authSeqId2 = _authSeqId2.toIntArray();
-        const labelAltId1 = _labelAltId1.toStringArray();
-        const labelAltId2 = _labelAltId2.toStringArray();
-        const stepIds = _stepIds.toIntArray();
-        const assignedNtCs = _assignedNtCs.toStringArray();
-        const closestNtCs = _closestNtCs.toStringArray();
-        const models = _models.toIntArray();
-        const len = ids.length;
-
+        const len = _ids.length;
         const stepNames = new Map<string, number>();
         const steps = new Array<StepInfo>(len);
 
         for (let idx = 0; idx < len; idx++) {
-            const id = ids[idx];
-            const name = names[idx];
+            const id = _ids[idx];
+            const name = _names[idx];
             for (let jdx = 0; jdx < len; jdx++) {
-                if (stepIds[jdx] === id) {
-                    const assignedNtC = assignedNtCs[jdx];
-                    const closestNtC = closestNtCs[jdx];
-                    const chain = chains[jdx];
-                    const resNo1 = authSeqId1[jdx];
-                    const resNo2 = authSeqId2[jdx];
-                    const altId1 = labelAltId1[jdx] === '' ? void 0 : labelAltId1[jdx];
-                    const altId2 = labelAltId2[jdx] === '' ? void 0 : labelAltId2[jdx];
-                    const model = models[jdx];
+                if (_stepIds[jdx] === id) {
+                    const assignedNtC = _assignedNtCs[jdx];
+                    const closestNtC = _closestNtCs[jdx];
+                    const chain = _chains[jdx];
+                    const resNo1 = _authSeqId1[jdx];
+                    const resNo2 = _authSeqId2[jdx];
+                    const compId1 = _compId1[jdx];
+                    const compId2 = _compId2[jdx];
+                    const altId1 = _labelAltId1[jdx] === '' ? void 0 : _labelAltId1[jdx];
+                    const altId2 = _labelAltId2[jdx] === '' ? void 0 : _labelAltId2[jdx];
+                    const insCode1 = _PDBinsCode1[jdx];
+                    const insCode2 = _PDBinsCode2[jdx];
+                    const model = _models[jdx];
 
                     // We're assuming that steps are ID'd with a contigious, monotonic sequence starting from 1
                     steps[id - 1] = {
@@ -758,8 +739,12 @@ export class ReDNATCOMspViewer {
                         chain,
                         resNo1,
                         resNo2,
+                        compId1,
+                        compId2,
                         altId1,
                         altId2,
+                        insCode1,
+                        insCode2,
                         model
                     };
                     stepNames.set(name, id - 1);
@@ -1019,15 +1004,15 @@ export class ReDNATCOMspViewer {
         this.resetCameraRadius();
     }
 
-    async actionSelectStep(stepName: string, stepNamePrev: string|undefined, stepNameNext: string|undefined, referenceNtc: string, references: ('sel'|'prev'|'next')[], display: Display): Promise<{ rmsd: number }|undefined> {
-        const stepCurrent = this.stepFromName(stepName);
-        if (!stepCurrent)
-            return void 0;
+    async actionSelectStep(stepSel: Api.Payloads.StepSelection, prevSel: Api.Payloads.StepSelection|undefined, nextSel: Api.Payloads.StepSelection|undefined, display: Display): Promise<{ rmsd: number }|undefined> {
+        const step = this.stepFromName(stepSel.name);
+        if (!step)
+            return;
 
         // Switch to a different model if the selected step is from a different model
         // This is the first thing we need to do
-        if (stepCurrent.model !== this.currentModelNumber())
-            await this.switchModel({ modelNumber: stepCurrent.model });
+        if (step.model !== this.currentModelNumber())
+            await this.switchModel({ modelNumber: step.model });
 
         const entireStruCell = this.plugin.state.data.cells.get(IDs.ID('structure', 'nucleic', BaseRef));
         if (!entireStruCell)
@@ -1035,29 +1020,23 @@ export class ReDNATCOMspViewer {
         const stru = entireStruCell.obj!.data!;
         const struLoci = StructureSelection.toLociWithSourceUnits(StructureSelection.Singletons(stru, stru));
 
-        const lociCurrent = Traverse.findStep(
-            stepCurrent.chain,
-            stepCurrent.resNo1,
-            stepCurrent.altId1,
-            struLoci,
-            'auth'
+        const stepLoci = Traverse.findStep(
+            step.chain,
+            step.resNo1, step.altId1, step.insCode1,
+            step.resNo2, step.altId2, step.insCode2,
+            struLoci, 'auth'
         );
-        if (lociCurrent.kind !== 'element-loci')
-            return void 0;
-
-        const current = {
-            step: stepCurrent,
-            loci: lociCurrent,
-        };
+        if (stepLoci.kind !== 'element-loci')
+            return;
 
-        const prev = stepNamePrev ? this.toStepWithStructure(stepNamePrev, struLoci) : undefined;
-        const next = stepNameNext ? this.toStepWithStructure(stepNameNext, struLoci) : undefined;
+        const prevLoci = prevSel ? this.toStepLoci(prevSel.name, struLoci) : EmptyLoci;
+        const nextLoci = nextSel ? this.toStepLoci(nextSel.name, struLoci) : EmptyLoci;
 
-        const toUnionize = [StructureElement.Loci.toStructure(current.loci)];
-        if (prev)
-            toUnionize.push(StructureElement.Loci.toStructure(prev.loci));
-        if (next)
-            toUnionize.push(StructureElement.Loci.toStructure(next.loci));
+        const toUnionize = [stepLoci.structure];
+        if (prevLoci.kind !== 'empty-loci')
+            toUnionize.push(prevLoci.structure);
+        if (nextLoci.kind !== 'empty-loci')
+            toUnionize.push(nextLoci.structure);
 
         const slice = structureUnion(stru, toUnionize);
         const stepBundle = StructureElement.Bundle.fromSubStructure(stru, slice);
@@ -1096,13 +1075,14 @@ export class ReDNATCOMspViewer {
                 .delete(IDs.ID('visual', 'nucleic', BaseRef));
         }
 
-        const rmsd = this.superposeReferences(b.toRoot(), current, prev, next, referenceNtc, references);
-        if (!rmsd)
-            return void 0;
+        this.superposeReferences(
+            b.toRoot(),
+            stepSel.reference ? { loci: stepLoci, reference: stepSel.reference } : void 0,
+            prevSel?.reference && prevLoci.kind === 'element-loci' ? { loci: prevLoci, reference: prevSel.reference } : void 0,
+            nextSel?.reference && nextLoci.kind === 'element-loci' ? { loci: nextLoci, reference: nextSel.reference } : void 0
+        );
 
         await b.commit();
-
-        return { rmsd };
     }
 
     async switchModel(display: Partial<Display>) {
@@ -1125,7 +1105,12 @@ export class ReDNATCOMspViewer {
         await b.commit();
     }
 
-    superposeReferences<A extends StateObject, T extends StateTransformer>(b: StateBuilder.To<A, T>, current: StepWithStructure, prev: StepWithStructure|undefined, next: StepWithStructure|undefined, referenceNtc: string, references: ('sel'|'prev'|'next')[]) {
+    superposeReferences<A extends StateObject, T extends StateTransformer>(
+        b: StateBuilder.To<A, T>,
+        step?: { loci: StructureElement.Loci, reference: Api.Payloads.StepSelection['reference'] },
+        prev?: { loci: StructureElement.Loci, reference: Api.Payloads.StepSelection['reference'] },
+        next?: { loci: StructureElement.Loci, reference: Api.Payloads.StepSelection['reference'] }
+    ) {
         const ReferenceVisuals = (color: number) => {
             return {
                 type: { name: 'ball-and-stick', params: { sizeFactor: 0.15, aromaticBonds: false } },
@@ -1133,49 +1118,43 @@ export class ReDNATCOMspViewer {
             };
         };
 
-        const ntcRefSel = this.ntcRef(current.step, 'sel')!;
-        const ntcRefPrev = prev ? this.ntcRef(prev.step, 'prev') : undefined;
-        const ntcRefNext = next ? this.ntcRef(next?.step, 'next') : undefined;
-
         b.delete(IDs.ID('superposition', '', NtCSupSel))
             .delete(IDs.ID('superposition', '', NtCSupPrev))
             .delete(IDs.ID('superposition', '', NtCSupNext));
 
-        const addReference = (ntcRef: string, superposRef: string, loci: StructureElement.Loci, altId1: string|undefined, altId2: string|undefined, color: number) => {
+        const addReference = (ntcRef: string, superposRef: string, stepLoci: StructureElement.Loci, color: number) => {
             const refStru = this.plugin.state.data.cells.get(IDs.ID('structure', '', ntcRef))!.obj!;
             const refLoci = StructureSelection.toLociWithSourceUnits(StructureSelection.Singletons(refStru.data, refStru.data));
 
-            if (Step.is(loci)) {
-                const { bTransform, rmsd } = this.superpose(refLoci, loci, altId1, altId2);
-                if (isNaN(bTransform[0])) {
-                    console.error(`Cannot superpose reference conformer ${ntcRef} onto selection`);
-                    return void 0;
-                }
-                b.to(IDs.ID('structure', '', ntcRef))
-                    .apply(
-                        StateTransforms.Model.TransformStructureConformation,
-                        { transform: { name: 'matrix', params: { data: bTransform, transpose: false } } },
-                        { ref: IDs.ID('superposition', '', superposRef) }
-                    ).apply(
-                        StateTransforms.Representation.StructureRepresentation3D,
-                        ReferenceVisuals(color),
-                        { ref: IDs.ID('visual', '', superposRef) }
-                    );
-                return rmsd;
+            const { bTransform } = this.superpose(refLoci, stepLoci);
+            if (isNaN(bTransform[0])) {
+                console.error(`Cannot superpose reference conformer ${ntcRef} onto selection`);
+                return;
             }
+            b.to(IDs.ID('structure', '', ntcRef))
+                .apply(
+                    StateTransforms.Model.TransformStructureConformation,
+                    { transform: { name: 'matrix', params: { data: bTransform, transpose: false } } },
+                    { ref: IDs.ID('superposition', '', superposRef) }
+                ).apply(
+                    StateTransforms.Representation.StructureRepresentation3D,
+                    ReferenceVisuals(color),
+                    { ref: IDs.ID('visual', '', superposRef) }
+                );
         };
 
-        const rmsd = addReference(ntcRefSel, NtCSupSel, current.loci, current.step.altId1, current.step.altId2, 0x008000);
-        if (ntcRefPrev) {
-            const { altId1, altId2 } = prev!.step;
-            addReference(ntcRefPrev, NtCSupPrev, prev!.loci, altId1, altId2, 0x0000FF);
+        if (step?.reference) {
+            const ref = this.ntcRef(step.reference.NtC, 'sel');
+            addReference(ref, NtCSupSel, step.loci, step.reference.color);
         }
-        if (ntcRefNext) {
-            const { altId1, altId2 } = next!.step;
-            addReference(ntcRefNext, NtCSupNext, next!.loci, altId1, altId2, 0x00FFFF);
+        if (prev?.reference) {
+            const ref = this.ntcRef(prev.reference.NtC, 'prev');
+            addReference(ref, NtCSupPrev, prev.loci, prev.reference.color);
+        }
+        if (next?.reference) {
+            const ref = this.ntcRef(next?.reference.NtC, 'next');
+            addReference(ref, NtCSupNext, next.loci, next.reference.color);
         }
-
-        return rmsd;
     }
 
     async toggleSubstructure(sub: IDs.Substructure, display: Display) {