     }
   }}
 
+  fileprivate static var installRoute: ActionRoute { get {
+    return ActionRoute.postRaw(EventName.Install) { data in
+      let guid = UUID().uuidString
+      let ipaURL = URL(fileURLWithPath: NSTemporaryDirectory())
+        .appendingPathComponent("fbsimctl-\(guid)")
+        .appendingPathExtension("ipa")
+
+      if (FileManager.default.fileExists(atPath: ipaURL.path)) {
+        throw ParseError.custom("Could not generate temporary filename, \(ipaURL.path) already exists.")
+      }
+      try data.write(to: ipaURL)
+      return HttpAction(Action.install(ipaURL.path)) {
+        try? FileManager.default.removeItem(at: ipaURL)
+      }
+    }
+  }}
+
   fileprivate static var launchRoute: ActionRoute { get {
     return ActionRoute.post(EventName.Launch) { json in
       if let agentLaunch = try? FBAgentLaunchConfiguration.inflate(fromJSON: json.decode()) {


  static func post(_ endpoint: EventName, handler: @escaping (JSON) throws -> HttpAction) -> ActionRoute {
    return ActionRoute(method: HttpMethod.POST, endpoint: endpoint, handler: Handler.parser(handler))
  }

  static func getConstant(_ endpoint: EventName, action: HttpAction) -> ActionRoute {

    case constant(HttpAction)
    case path(([String]) throws -> HttpAction)
    case parser((JSON) throws -> HttpAction)
    case binary((Data) throws -> HttpAction)
  }

  let method: HttpMethod
