code: @Override
      public MonetaryAmount apply(MonetaryAmount value) {
          Objects.requireNonNull(value, "Amount required.");
          // 1 extract BD value, round according the default fraction units
          int scale = this.context.getInt(SCALE_KEY);
          RoundingMode roundingMode = this.context.get(RoundingMode.class);
          BigDecimal num = value.getNumber().numberValue(BigDecimal.class).setScale(scale, roundingMode);
          // 2 evaluate minor units and remainder
          long minors = num.movePointRight(num.scale()).longValueExact();
          int minimalMinors = this.context.getInt(MINMINORS_KEY);
          long factor = minors / minimalMinors;
          long low = minimalMinors * factor;
          long high = minimalMinors * (factor + 1);
          if (minors - low > high - minors) {
              minors = high;
          } else if (minors - low < high - minors) {
              minors = low;
          } else {
              switch (roundingMode) {
                  case HALF_UP:
                  case UP:
                  case HALF_EVEN:
                      minors = high;
                      break;
                  default:
                      minors = low;
              }
          }
          return value.getFactory().setCurrency(value.getCurrency())
                  .setNumber(BigDecimal.valueOf(minors).movePointLeft(scale)).create();
      }
docs: /*
  (non-Javadoc)
  
  @see org.javamoney.bp.api.MonetaryFunction#apply(java.lang.Object)