// Path: src/main/java/com/github/rinde/logistics/pdptw/mas/comm/AuctionCommModel.java
// public static class AuctionEvent extends Event {
//   private final Parcel parcel;
//   private final long auctionStartTime;
//   private final long time;
//   private final Optional<Bidder<?>> winner;
//   private final int receivedBids;
// 
//   AuctionEvent(Enum<?> type, Parcel p, Auctioneer a, long auctStart, long t) {
//     this(type, p, a, auctStart, t, -1);
//   }
// 
//   AuctionEvent(Enum<?> type, Parcel p, Auctioneer a, long auctStart, long t,
//       int numBids) {
//     super(type);
//     parcel = p;
//     auctionStartTime = auctStart;
//     time = t;
//     receivedBids = numBids;
//     if (type == EventType.FINISH_AUCTION) {
//       winner = Optional.<Bidder<?>>of(a.getWinner());
//     } else {
//       winner = Optional.absent();
//     }
//   }
// 
//   @Override
//   public String toString() {
//     return MoreObjects.toStringHelper(AuctionEvent.class)
//       .add("type", getEventType())
//       .add("parcel", parcel)
//       .add("winner", winner)
//       .add("time", time)
//       .toString();
//   }
// 
//   /**
//    * @return the parcel
//    */
//   public Parcel getParcel() {
//     return parcel;
//   }
// 
//   public int getNumBids() {
//     return receivedBids;
//   }
// 
//   public Optional<Bidder<?>> getWinner() {
//     return winner;
//   }
// 
//   public long getAuctionStartTime() {
//     return auctionStartTime;
//   }
// 
//   public long getTime() {
//     return time;
//   }
// }


import com.google.common.collect.ListMultimap;
import java.util.ArrayList;
import java.util.List;
import com.github.rinde.logistics.pdptw.mas.comm.AuctionCommModel.AuctionEvent;
import com.github.rinde.rinsim.central.Measurable;
import com.github.rinde.rinsim.central.SolverTimeMeasurement;
import com.github.rinde.rinsim.core.model.DependencyProvider;
import com.github.rinde.rinsim.core.model.Model.AbstractModel;
import com.github.rinde.rinsim.core.model.ModelBuilder.AbstractModelBuilder;
import com.github.rinde.rinsim.event.Event;
import com.github.rinde.rinsim.event.Listener;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
/*
 * Copyright (C) 2013-2016 Rinde van Lon, iMinds-DistriNet, KU Leuven
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.github.rinde.logistics.pdptw.mas.comm;



/**
 * Utility for keeping track of auction related statistics. To use it, simply
 * add {@link #builder()} to a simulation configuration. The statistics that are
 * tracked are all finished {@link AuctionEvent}s and using
 * {@link #getTimeMeasurements()} all time measurements can be collected.
 * @author Rinde van Lon
 */
public class AuctionTimeStatsLogger extends AbstractModel<Bidder<DoubleBid>> {
  final List<AuctionEvent> finishEvents;
  private final List<Bidder<DoubleBid>> bidders;

  AuctionTimeStatsLogger(AuctionCommModel<?> model) {
    finishEvents = new ArrayList<>();
    bidders = new ArrayList<>();

    model.getEventAPI().addListener(new Listener() {
      @Override
      public void handleEvent(Event e) {
// Path: src/main/java/com/github/rinde/logistics/pdptw/mas/comm/AuctionCommModel.java
// public static class AuctionEvent extends Event {
//   private final Parcel parcel;
//   private final long auctionStartTime;
//   private final long time;
//   private final Optional<Bidder<?>> winner;
//   private final int receivedBids;
// 
//   AuctionEvent(Enum<?> type, Parcel p, Auctioneer a, long auctStart, long t) {
//     this(type, p, a, auctStart, t, -1);
//   }
// 
//   AuctionEvent(Enum<?> type, Parcel p, Auctioneer a, long auctStart, long t,
//       int numBids) {
//     super(type);
//     parcel = p;
//     auctionStartTime = auctStart;
//     time = t;
//     receivedBids = numBids;
//     if (type == EventType.FINISH_AUCTION) {
//       winner = Optional.<Bidder<?>>of(a.getWinner());
//     } else {
//       winner = Optional.absent();
//     }
//   }
// 
//   @Override
//   public String toString() {
//     return MoreObjects.toStringHelper(AuctionEvent.class)
//       .add("type", getEventType())
//       .add("parcel", parcel)
//       .add("winner", winner)
//       .add("time", time)
//       .toString();
//   }
// 
//   /**
//    * @return the parcel
//    */
//   public Parcel getParcel() {
//     return parcel;
//   }
// 
//   public int getNumBids() {
//     return receivedBids;
//   }
// 
//   public Optional<Bidder<?>> getWinner() {
//     return winner;
//   }
// 
//   public long getAuctionStartTime() {
//     return auctionStartTime;
//   }
// 
//   public long getTime() {
//     return time;
//   }
// }


// Path: src/main/java/com/github/rinde/logistics/pdptw/mas/comm/AuctionTimeStatsLogger.java
import com.google.common.collect.ListMultimap;
import java.util.ArrayList;
import java.util.List;
import com.github.rinde.logistics.pdptw.mas.comm.AuctionCommModel.AuctionEvent;
import com.github.rinde.rinsim.central.Measurable;
import com.github.rinde.rinsim.central.SolverTimeMeasurement;
import com.github.rinde.rinsim.core.model.DependencyProvider;
import com.github.rinde.rinsim.core.model.Model.AbstractModel;
import com.github.rinde.rinsim.core.model.ModelBuilder.AbstractModelBuilder;
import com.github.rinde.rinsim.event.Event;
import com.github.rinde.rinsim.event.Listener;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;

/*
 * Copyright (C) 2013-2016 Rinde van Lon, iMinds-DistriNet, KU Leuven
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.github.rinde.logistics.pdptw.mas.comm;



/**
 * Utility for keeping track of auction related statistics. To use it, simply
 * add {@link #builder()} to a simulation configuration. The statistics that are
 * tracked are all finished {@link AuctionEvent}s and using
 * {@link #getTimeMeasurements()} all time measurements can be collected.
 * @author Rinde van Lon
 */
public class AuctionTimeStatsLogger extends AbstractModel<Bidder<DoubleBid>> {
  final List<AuctionEvent> finishEvents;
  private final List<Bidder<DoubleBid>> bidders;

  AuctionTimeStatsLogger(AuctionCommModel<?> model) {
    finishEvents = new ArrayList<>();
    bidders = new ArrayList<>();

    model.getEventAPI().addListener(new Listener() {
      @Override
      public void handleEvent(Event e) {
        finishEvents.add((AuctionEvent) e);