A seller registers its service (selling whiskey) with the local DF agent, then adds a seller behavior.
public class Seller extends Agent {
    protected void setup() {
      DFAgentDescription dfd = new
DFAgentDescription();
      dfd.setName(getAID());
      ServiceDescription service  = new ServiceDescription();
         service.setType(
"whiskey" );
         service.setName(
getLocalName() );
      try {
         DFAgentDescription
list[] = DFService.search( this, dfd );
         if ( list.length > 0 )
DFService.deregister(this);
            dfd.addServices(service);
         DFService.register(this, dfd);
      } catch (FIPAException fe) {
         System.err.println(fe.getMessage());
      }
      addBehaviour(new
SellerBehavior(this));
   }
}
Selling whiskey is a cyclic behavior. It blocks until it receives an appropriate message, then creates an appropriate reply and sends it after some delay:
class SellerBehavior extends CyclicBehaviour {
   MessageTemplate template =
      MessageTemplate.MatchPerformative(
ACLMessage.QUERY_REF );
   ACLMessage reply;
   Random generator = new Random();
   public SellerBehavior(Agent a) {
super(a); }
   public void action() {
      int price =
generator.nextInt(500);  // price per
bottle
      int delay =
generator.nextInt(100); // respond after delay
      ACLMessage msg =
myAgent.receive(template);
      if (msg != null) {
         reply = msg.createReply();
         reply.setPerformative(
ACLMessage.INFORM );
           
reply.setContent("" + price);
           
System.out.print(myAgent.getLocalName());
            System.out.print("
will offer $" + price + " to ");
           
System.out.print(msg.getSender().getLocalName());
           
System.out.println(" in " + delay + " ms");
            myAgent.addBehaviour(
            new DelayBehaviour(myAgent,
delay) {
                  public void
handleElapsedTimeout() {
                           myAgent.send(reply);
                     }
                    });
         } // if
         block();
     } // action
}
A buyer finds out which agents sell whiskey. It adds each one to the receivers list for a request for whiskey. It creates a sequential behavior consisting of a parallel behavior followed by a one shot behavior that prints the lowest bid. The parallel behavior consists of a buyer behavior for each seller:
public class Buyer extends Agent {
   int bestPrice = 9999999;
   ACLMessage bestOffer = null;
   protected void setup() {
      AID[] providers =
DFUtils.searchDF(this, "whiskey");
      if (providers != null) {
         SequentialBehaviour seq = new
SequentialBehaviour();
         ParallelBehaviour
par = 
            new ParallelBehaviour(
ParallelBehaviour.WHEN_ALL );
         ACLMessage
msg = new ACLMessage(ACLMessage.QUERY_REF);
         String
id = "whiskey request";
         msg.setConversationId(id);
         msg.setContent(
"how much?" );
         for(int i = 0; i <
providers.length; i++) {
             msg.addReceiver(providers[i]);
             MessageTemplate template = MessageTemplate.and(
               MessageTemplate.MatchPerformative(ACLMessage.INFORM),
               MessageTemplate.MatchConversationId(id));
             par.addSubBehaviour(
               new BuyerBehavior(this,
2000, template));
             send(msg);
         } // for
         seq.addSubBehaviour( par );
         addBehaviour( seq );
         seq.addSubBehaviour(
            new OneShotBehaviour() {
               public void action() {
                  if (bestOffer != null)
                     System.out.println("Best
Price $" + bestPrice );
                  else
                     System.out.println("Got
no quotes");
               }
         );
         send(msg); 
      } // if
    } // setup
} // Buyer
class BuyerBehavior extends MyReceiver {
   public BuyerBehavior(
      Agent a, int delay, MessageTemplate
template ) {
         super(a, delay, template);
   }
   public void handle( ACLMessage msg) {
      if
(msg == null) return;
      int
offer = Integer.parseInt( msg.getContent());
      System.out.println("Buyer
considering an offer for $" + offer);
      if (offer <
((Buyer)myAgent).bestPrice) {
         ((Buyer)myAgent).bestPrice
= offer;
            ((Buyer)myAgent).bestOffer =
msg;
      }
   }
}
s1 will offer $227 to b1 in 66 ms
s3 will offer $173 to b1 in 86 ms
s2 will offer $75 to b1 in 65 ms
s1 will offer $323 to b1 in 29 ms
s3 will offer $105 to b1 in 44 ms
s2 will offer $114 to b1 in 18 ms
Buyer considering an offer for $114
Buyer considering an offer for $323
Buyer considering an offer for $105
Best Price $105