private void PrepareStereochemistry(int u, int prev) { Topology topology = g.TopologyOf(u); if (topology != Topology.Unknown) { if (rings.TryGetValue(u, out IList <RingClosure> closures)) { // most of time we only have a single closure, we can // handle this easily by moving the ranks of the prev // and curr atom back and using the curr rank for the // ring if (closures.Count == 1) { int ring = closures[0].Other(u); int uAt = visitedAt[u]; int rAt = visitedAt[ring]; visitedAt[prev]--; visitedAt[u]--; visitedAt[ring] = uAt; tokens[u].Configure(topology.ConfigurationOf(visitedAt)); // restore visitedAt[prev]++; visitedAt[u]++; visitedAt[ring] = rAt; } else { // more complicated, we first move the other two atoms out // the way then store and change the current ranks of the // ring atoms. We restore all visitedAt once we exit Trace.Assert(closures.Count <= 4); visitedAt[prev] -= 4; visitedAt[u] -= 4; int rank = visitedAt[u]; for (int i = 0; i < closures.Count; ++i) { int v = closures[i].Other(u); tmp[i] = visitedAt[v]; visitedAt[v] = ++rank; } tokens[u].Configure(topology.ConfigurationOf(visitedAt)); // restore for (int i = 0; i < closures.Count; ++i) { visitedAt[closures[i].Other(u)] = tmp[i]; } visitedAt[prev] += 4; visitedAt[u] += 4; } } else { tokens[u].Configure(topology.ConfigurationOf(visitedAt)); } } }