// Path: job/src/main/java/com/palominolabs/benchpress/job/json/Task.java
// public final class Task {
//     private final String taskType;
// 
//     private final JsonNode configNode;
// 
//     /**
//      * @param taskType   task type
//      * @param configNode config json. This claims ownership of the node object.
//      */
//     @JsonCreator
//     public Task(@JsonProperty("type") String taskType, @JsonProperty("config") JsonNode configNode) {
//         this.taskType = taskType;
//         this.configNode = configNode;
//     }
// 
//     /**
//      * Don't mess with this JsonNode; just read from it.
//      *
//      * @return json node representing the config data. {@link ComponentFactory} implementations should deserialize as
//      * they see fit.
//      */
//     @JsonProperty("config")
//     public JsonNode getConfigNode() {
//         return this.configNode;
//     }
// 
//     /**
//      * Should match the {@link Identifiable} implementation on a {@link ComponentFactory}
//      *
//      * @return the task type
//      */
//     @JsonProperty("type")
//     public String getTaskType() {
//         return taskType;
//     }
// }
// 
// Path: worker-data/src/main/java/com/palominolabs/benchpress/worker/WorkerMetadata.java
// @Immutable
// public final class WorkerMetadata {
// 
//     @JsonProperty("workerId")
//     private final UUID workerId;
// 
//     @JsonProperty("listenAddress")
//     private final String listenAddress;
// 
//     @JsonProperty("listenPort")
//     private final int listenPort;
// 
//     @JsonCreator
//     public WorkerMetadata(@JsonProperty("workerId") UUID workerId, @JsonProperty("listenAddress") String listenAddress,
//                           @JsonProperty("listenPort") int listenPort) {
//         this.workerId = workerId;
//         this.listenAddress = listenAddress;
//         this.listenPort = listenPort;
//     }
// 
//     public UUID getWorkerId() {
//         return workerId;
//     }
// 
//     public String getListenAddress() {
//         return listenAddress;
//     }
// 
//     public int getListenPort() {
//         return listenPort;
//     }
// 
//     public String toString() {
//         return workerId.toString() + " (" + listenAddress + ":" + listenPort + ")";
//     }
// }


import com.fasterxml.jackson.databind.JsonNode;
import com.palominolabs.benchpress.job.json.Task;
import com.palominolabs.benchpress.worker.WorkerMetadata;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe;
package com.palominolabs.benchpress.controller;


@NotThreadSafe
class SliceMetadata {
    private final Task task;

    /**
     * The worker that was given this slice
     */
    private final WorkerMetadata workerMetadata;

    @Nullable
    private Duration finalDuration;

    private final List<ProgressItem> progress =new ArrayList<>();

// Path: job/src/main/java/com/palominolabs/benchpress/job/json/Task.java
// public final class Task {
//     private final String taskType;
// 
//     private final JsonNode configNode;
// 
//     /**
//      * @param taskType   task type
//      * @param configNode config json. This claims ownership of the node object.
//      */
//     @JsonCreator
//     public Task(@JsonProperty("type") String taskType, @JsonProperty("config") JsonNode configNode) {
//         this.taskType = taskType;
//         this.configNode = configNode;
//     }
// 
//     /**
//      * Don't mess with this JsonNode; just read from it.
//      *
//      * @return json node representing the config data. {@link ComponentFactory} implementations should deserialize as
//      * they see fit.
//      */
//     @JsonProperty("config")
//     public JsonNode getConfigNode() {
//         return this.configNode;
//     }
// 
//     /**
//      * Should match the {@link Identifiable} implementation on a {@link ComponentFactory}
//      *
//      * @return the task type
//      */
//     @JsonProperty("type")
//     public String getTaskType() {
//         return taskType;
//     }
// }
// 
// Path: worker-data/src/main/java/com/palominolabs/benchpress/worker/WorkerMetadata.java
// @Immutable
// public final class WorkerMetadata {
// 
//     @JsonProperty("workerId")
//     private final UUID workerId;
// 
//     @JsonProperty("listenAddress")
//     private final String listenAddress;
// 
//     @JsonProperty("listenPort")
//     private final int listenPort;
// 
//     @JsonCreator
//     public WorkerMetadata(@JsonProperty("workerId") UUID workerId, @JsonProperty("listenAddress") String listenAddress,
//                           @JsonProperty("listenPort") int listenPort) {
//         this.workerId = workerId;
//         this.listenAddress = listenAddress;
//         this.listenPort = listenPort;
//     }
// 
//     public UUID getWorkerId() {
//         return workerId;
//     }
// 
//     public String getListenAddress() {
//         return listenAddress;
//     }
// 
//     public int getListenPort() {
//         return listenPort;
//     }
// 
//     public String toString() {
//         return workerId.toString() + " (" + listenAddress + ":" + listenPort + ")";
//     }
// }


// Path: controller-core/src/main/java/com/palominolabs/benchpress/controller/SliceMetadata.java
import com.fasterxml.jackson.databind.JsonNode;
import com.palominolabs.benchpress.job.json.Task;
import com.palominolabs.benchpress.worker.WorkerMetadata;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe;

package com.palominolabs.benchpress.controller;


@NotThreadSafe
class SliceMetadata {
    private final Task task;

    /**
     * The worker that was given this slice
     */
    private final WorkerMetadata workerMetadata;

    @Nullable
    private Duration finalDuration;

    private final List<ProgressItem> progress =new ArrayList<>();

    SliceMetadata(Task task, WorkerMetadata workerMetadata) {