 
 // Namespacing some sub-types
 extension Departure {
-    public enum State {
-        case onTime
-        case delayed
-        case other(String) // TODO: Figure out what these are. "Cancelled" maybe? And others?
-        case unknown
+    public struct State: Decodable {
+        public let rawValue: String
 
-        init(_ string: String) {
-            switch string {
-            case "InTime": self = .onTime
-            case "Delayed": self = .delayed
-            default: self = .other(string)
+        public static let onTime = State(value: "InTime")
+        public static let delayed = State(value: "Delayed")
+
+        init(value: String) {
+            switch value {
+            case "InTime": self = State.onTime
+            case "Delayed": self = State.delayed
+            default:
+                self.rawValue = value
             }
+        }
+
+        public init(from decoder: Decoder) throws {
+            let container = try decoder.singleValueContainer()
+            self.init(value: try container.decode(String.self))
         }
     }
 

    }
}

// MARK: - JSON

extension MonitorResponse: Unmarshaling {
    public init(object: MarshaledObject) throws {
        stopName = try object <| "Name"
        place = try object <| "Place"
        expirationTime = try object <| "ExpirationTime"
        departures = try object <| "Departures"
    }
}

extension Departure: Unmarshaling {
    public init(object: MarshaledObject) throws {
        id = try object <| "Id"
        line = try object <| "LineName"
        direction = try object <| "Direction"
        mode = try object <| "Mot"

        scheduledTime = try object <| "ScheduledTime"
        routeChanges = try object <| "RouteChanges"
        platform = try object <| "Platform"
        diva = try object <| "Diva"
        realTime = try object <| "RealTime"

        let rawState: String? = try object <| "State"
        if let stateString = rawState {
            state = try Departure.State.value(from: stateString)
        } else {
            state = .unknown
        }
    }
}

extension Departure.State: ValueType {
    public static func value(from object: Any) throws -> Departure.State {
        guard let stateStr = object as? String else {
            throw MarshalError.typeMismatch(expected: String.self, actual: type(of: object))
        }
        return self.init(stateStr)
    }
}

// MARK: - API

extension Departure {
    public static func monitor(stopWithId id: String, date: Date = Date(), dateType: DateType = .arrival, allowedModes modes: [Mode] = Mode.all, allowShorttermChanges: Bool = true, session: URLSession = .shared, completion: @escaping (Result<MonitorResponse>) -> Void) {
        let data: [String: Any] = [
            "stopid": id,
            "time": date.iso8601,

        return self.id.hashValue
    }
}
