--- /dev/null
+package jalview.datamodel.features;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Each node of the NCList tree consists of a range, and (optionally) the NCList
+ * of ranges it encloses
+ *
+ * @param <V>
+ */
+class NCNode<V extends ContiguousI>
+{
+ /*
+ * deep size (number of ranges included)
+ */
+ private int size;
+
+ private V region;
+
+ private NCList<V> subregions;
+
+ /**
+ * Constructor
+ *
+ * @param ranges
+ */
+ NCNode(List<V> ranges)
+ {
+ build(ranges);
+ }
+
+ /**
+ * Constructo
+ *
+ * @param range
+ */
+ NCNode(V range)
+ {
+ List<V> ranges = new ArrayList<V>();
+ ranges.add(range);
+ build(ranges);
+ }
+
+ /**
+ * @param ranges
+ */
+ protected void build(List<V> ranges)
+ {
+ size = ranges.size();
+
+ if (!ranges.isEmpty())
+ {
+ region = ranges.get(0);
+ }
+ if (ranges.size() > 1)
+ {
+ subregions = new NCList<V>(ranges.subList(1, ranges.size()));
+ }
+ }
+
+ int getStart()
+ {
+ return region.getBegin();
+ }
+
+ int getEnd()
+ {
+ return region.getEnd();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder(10 * size);
+ sb.append(region.getBegin()).append("-").append(region.getEnd());
+ if (subregions != null)
+ {
+ sb.append(" ").append(subregions.toString());
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Add any ranges that overlap the from-to range to the result list
+ *
+ * @param from
+ * @param to
+ * @param result
+ */
+ void addOverlaps(long from, long to, List<V> result)
+ {
+ if (region.getBegin() <= to && region.getEnd() >= from)
+ {
+ result.add(region);
+ }
+ if (subregions != null)
+ {
+ subregions.findOverlaps(from, to, result);
+ }
+ }
+
+ /**
+ * Add one range to this subrange
+ *
+ * @param entry
+ */
+ public synchronized void add(V entry)
+ {
+ if (entry.getBegin() < region.getBegin() || entry.getEnd() > region.getEnd()) {
+ throw new IllegalArgumentException(String.format(
+ "adding improper subrange %d-%d to range %d-%d",
+ entry.getBegin(), entry.getEnd(), region.getBegin(),
+ region.getEnd()));
+ }
+ if (subregions == null)
+ {
+ subregions = new NCList<V>(entry);
+ }
+ else
+ {
+ subregions.add(entry);
+ }
+ }
+}