public Behaviour jobFor(Actor actor) {
    if ((! structure.intact()) || (! personnel.onShift(actor))) return null ;
    final Choice choice = new Choice(actor) ;
    
    final int linkMod = (int) (5 * (1 - stocks.shortagePenalty(DATALINKS))) ;
    
    if (actor.vocation() == Background.AUDITOR) {
      final Venue toAudit = Audit.nextToAuditFor(actor) ;
      if (toAudit != null) {
        final Audit a = new Audit(actor, toAudit) ;
        a.checkBonus = ((structure.upgradeLevel(FILE_SYSTEM) - 1) * 5) / 2 ;
        a.checkBonus += linkMod ;
        choice.add(a) ;
      }
      //
      //  TODO:  The Auditor needs to sift data and approve stories for
      //  publication.  Use local information only.
    }
    
    if (actor.vocation() == Background.ADVERTISER) {
      Batch <Venue> clients = new Batch <Venue> () ;
      world.presences.sampleFromKey(this, world, 5, clients, Holding.class) ;
      
      final Delivery c = Deliveries.nextCollectionFor(
        actor, this, new Service[] { PLASTICS }, 5, null, world
      ) ;
      choice.add(c) ;
      
      final Delivery d = Deliveries.nextDeliveryFor(
        actor, this, services(), clients, 5, world
      ) ;
      if (d != null) d.shouldPay = null ;
      //
      //  TODO:  Modify this a bit, so that the advertiser needn't go back and
      //  forth all the time?
      choice.add(d) ;
      
      final Manufacture mP = stocks.nextManufacture(
        actor, PLASTICS_TO_PRESSFEED
      ) ;
      if (mP != null) {
        mP.checkBonus = ((structure.upgradeLevel(PRESS_OFFICE) - 1) * 5) / 2 ;
        mP.checkBonus += linkMod ;
        choice.add(mP) ;
      }
    }
    
    return choice.weightedPick() ;
  }