protected Behaviour getNextStep() {
    final Item match = Item.asMatch(SAMPLES, output) ;
    final float
      rawAmount = venue.stocks.amountOf(match),
      newAmount = venue.stocks.amountOf(output) ;
    
    if (output == ARTIFACTS) {
      //  TODO:  Either deliver to the nearest Artificer for closer inspection,
      //  or attempt re-assembly here.
      
      //
      //  TODO:  Deliver artifacts to where they can either be sold or re-used.
    }
    else {
      final Venue parent = ((Smelter) venue).parent ;
      if ((rawAmount == 0 && newAmount > 0) || newAmount >= BASE_AMOUNT) {
        final Delivery d = new Delivery(output, venue, parent) ;
        if (Plan.competition(d, parent, actor) == 0) return d ;
      }
      if (parent.stocks.amountOf(match) > 0) {
        final Item carried = Item.with(SAMPLES, output, BASE_AMOUNT, 0) ;
        final Delivery d = new Delivery(carried, parent, venue) ;
        if (Plan.competition(d, parent, actor) == 0) return d ;
      }
      if (rawAmount + newAmount >= BASE_AMOUNT) {
        final Action smelt = new Action(
          actor, venue,
          this, "actionSmelt",
          Action.REACH_DOWN, "Smelting "+output.name
        ) ;
        smelt.setPriority(Action.ROUTINE) ;
        return smelt ;
      }
    }
    
    return null ;
  }