bufr/src/main/java/ucar/nc2/iosp/bufr/DataDescriptorTreeConstructor.java
private void operate(List<DataDescriptor> tree) {
    if (tree == null) return;
    boolean hasAssFields = false;
    // boolean hasDpiFields = false;
    DataDescriptor.AssociatedField assField = null; // 02 04 Y

    Iterator<DataDescriptor> iter = tree.iterator();
    while (iter.hasNext()) {
      DataDescriptor dd = iter.next();

      if (dd.f == 2) {
        if (dd.x == 1) {
          changeWidth = (dd.y == 0) ? null : dd;
          iter.remove();

        } else if (dd.x == 2) {
          changeScale = (dd.y == 0) ? null : dd;
          iter.remove();
          // throw new UnsupportedOperationException("2-2-Y (change scale)");

        } else if (dd.x == 3) {
          changeRefval = (dd.y == 255) ? null : dd;
          iter.remove();
          // throw new UnsupportedOperationException("2-3-Y (change reference values)");  // untested - no examples

        } else if (dd.x == 4) {
          assField = (dd.y == 0) ? null : new DataDescriptor.AssociatedField(dd.y);
          iter.remove();
          hasAssFields = true;

        } else if (dd.x == 5) { // char data - this allows arbitrary string to be inserted
          dd.type = 1; // String
          dd.bitWidth = dd.y * 8;
          dd.name = "Note";

        } else if (dd.x == 6) {
          // see L3-82 (3.1.6.5)
          // "Y bits of data are described by the immediately following descriptor". could they speak English?
          iter.remove();
          if ((dd.y != 0) && iter.hasNext()) {  // fnmoc using 2-6-0 as cancel (apparently)
            DataDescriptor next = iter.next();
            next.bitWidth = dd.y;
          }

        } else if (dd.x == 7) {
          changeWtf = (dd.y == 0) ? null : dd;
          iter.remove();

        } else if (dd.x == 36) {
          if (iter.hasNext()) {
            DataDescriptor dpi_dd = iter.next(); // this should be a replicated data present field
            dpi = new DataPresentIndicator(tree, dpi_dd);
            dd.dpi = dpi;
            dpi_dd.dpi = dpi;
          }
          
        } else if ((dd.x == 37) && (dd.y == 255)) { // cancel dpi
          dpi = null;

        } else if ((dd.x == 24) && (dd.y == 255)) {
           dd.dpi = dpi;
        }

      } else if (dd.subKeys != null) {
        operate(dd.subKeys);

      } else if (dd.f == 0) {

        if (dd.type != 3) {  // numeric or string or enum, not compound
          if (changeWidth != null)
            dd.bitWidth += changeWidth.y-128;
          if (changeScale != null)
            dd.scale += changeScale.y-128;
          if (changeRefval != null)
            dd.refVal += changeRefval.y-128;  // LOOK wrong

          if (changeWtf != null && dd.type == 0) {
            // see I.2 – BUFR Table C — 4
            // For Table B elements, which are not CCITT IA5 (character data), code tables, or flag tables:
            //  1. Add Y to the existing scale factor
            //  2. Multiply the existing reference value by 10 Y
            //  3. Calculate ((10 x Y) + 2) ÷  3, disregard any fractional remainder and add the result to the existing bit width.
            // HAHAHAHAHAHAHAHA
            int y = changeWtf.y;
            dd.scale += y;
            dd.refVal *= Math.pow(10, y);
            int wtf = ((10 * y) + 2) /  3;
            dd.bitWidth += wtf;
          }
        }

        if ((dd.f == 0) && (assField != null)) {
          assField.nfields++;
          dd.assField = assField;
          assField.dataFldName = dd.name;
        }
      }
    }

    if (hasAssFields) addAssFields(tree);
    // if (hasDpiFields) addDpiFields(tree);
  }
private void operate(List<DataDescriptor> tree) {
    if (tree == null) return;
    boolean hasAssFields = false;
    // boolean hasDpiFields = false;
    DataDescriptor.AssociatedField assField = null; // 02 04 Y

    Iterator<DataDescriptor> iter = tree.iterator();
    while (iter.hasNext()) {
      DataDescriptor dd = iter.next();

      if (dd.f == 2) {
        if (dd.x == 1) {
          changeWidth = (dd.y == 0) ? null : dd;
          iter.remove();

        } else if (dd.x == 2) {
          changeScale = (dd.y == 0) ? null : dd;
          iter.remove();
          // throw new UnsupportedOperationException("2-2-Y (change scale)");

        } else if (dd.x == 3) {
          changeRefval = (dd.y == 255) ? null : dd;
          iter.remove();
          // throw new UnsupportedOperationException("2-3-Y (change reference values)");  // untested - no examples

        } else if (dd.x == 4) {
          assField = (dd.y == 0) ? null : new DataDescriptor.AssociatedField(dd.y);
          iter.remove();
          hasAssFields = true;

        } else if (dd.x == 5) { // char data - this allows arbitrary string to be inserted
          dd.type = 1; // String
          dd.bitWidth = dd.y * 8;
          dd.name = "Note";

        } else if (dd.x == 6) {
          // see L3-82 (3.1.6.5)
          // "Y bits of data are described by the immediately following descriptor". could they speak English?
          iter.remove();
          if ((dd.y != 0) && iter.hasNext()) {  // fnmoc using 2-6-0 as cancel (apparently)
            DataDescriptor next = iter.next();
            next.bitWidth = dd.y;
          }

        } else if (dd.x == 7) {
          changeWtf = (dd.y == 0) ? null : dd;
          iter.remove();

        } else if (dd.x == 36) {
          if (iter.hasNext()) {
            DataDescriptor dpi_dd = iter.next(); // this should be a replicated data present field
            dpi = new DataPresentIndicator(tree, dpi_dd);
            dd.dpi = dpi;
            dpi_dd.dpi = dpi;
          }
          
        } else if ((dd.x == 37) && (dd.y == 255)) { // cancel dpi
          dpi = null;

        } else if ((dd.x == 24) && (dd.y == 255)) {
           dd.dpi = dpi;
        }

      } else if (dd.subKeys != null) {
        operate(dd.subKeys);

      } else if (dd.f == 0) {

        if (dd.type != 3) {  // numeric or string or enum, not compound
          if (changeWidth != null)
            dd.bitWidth += changeWidth.y-128;
          if (changeScale != null)
            dd.scale += changeScale.y-128;
          if (changeRefval != null)
            dd.refVal += changeRefval.y-128;  // LOOK wrong

          if (changeWtf != null && dd.type == 0) {
            // see I.2 – BUFR Table C — 4
            // For Table B elements, which are not CCITT IA5 (character data), code tables, or flag tables:
            //  1. Add Y to the existing scale factor
            //  2. Multiply the existing reference value by 10 Y
            //  3. Calculate ((10 x Y) + 2) ÷  3, disregard any fractional remainder and add the result to the existing bit width.
            // HAHAHAHAHAHAHAHA
            int y = changeWtf.y;
            dd.scale += y;
            dd.refVal *= Math.pow(10, y);
            int wtf = ((10 * y) + 2) /  3;
            dd.bitWidth += wtf;
          }
        }

        if ((dd.f == 0) && (assField != null)) {
          assField.nfields++;
          dd.assField = assField;
          assField.dataFldName = dd.name;
        }
      }
    }

    if (hasAssFields) addAssFields(tree);
    // if (hasDpiFields) addDpiFields(tree);
  }
assume theres only one in effect at a time