 class IOKeyEventMonitor{
   private
   let hidManager:IOHIDManager
+  let notificationCenter :CFNotificationCenter
   let match:CFMutableDictionary
-  var lastSeenSender:String=""
+  
+  var lastActiveKeyboard:String=""
+  var kb2is:[String: TISInputSource]=[String: TISInputSource]()
+  
   
   private class func createDeviceMatchingDictionary( usagePage:Int,  usage:Int ) -> CFMutableDictionary {
     let dict = [

  
  init? ( usagePage:Int,  usage:Int ){
    hidManager = IOHIDManagerCreate( kCFAllocatorDefault, IOOptionBits(kIOHIDOptionsTypeNone) );
    match=IOKeyEventMonitor.createDeviceMatchingDictionary(usagePage:usagePage, usage:usage);
    IOHIDManagerSetDeviceMatching( hidManager, match );
  }
  deinit {
    // FIXME find out how to pass nil as an IOKit.IOHIDValueCallback to unregister the callback
    //    IOHIDManagerRegisterInputValueCallback( hidManager, nil as IOKit.IOHIDValueCallback, nil);
  }
  func start()-> Void {
    
    let myHIDKeyboardCallback: IOHIDValueCallback={
      (context, ioreturn, sender, value) in
      let selfPtr = Unmanaged<IOKeyEventMonitor>.fromOpaque(context!).takeUnretainedValue();
      let sender = Unmanaged<IOKeyEventMonitor>.fromOpaque(sender!).takeUnretainedValue();
      let senderStr = String(describing:sender);
      
      if(selfPtr.lastSeenSender != senderStr){
        print("sender \(context!)");
        print("sender \(sender)");
        selfPtr.lastSeenSender = senderStr;
      }
    }
    
    let context = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque());
    print("start context \(context)");
    IOHIDManagerRegisterInputValueCallback( hidManager, myHIDKeyboardCallback, context);
    IOHIDManagerScheduleWithRunLoop( hidManager, CFRunLoopGetMain(), CFRunLoopMode.defaultMode!.rawValue);
    IOHIDManagerOpen( hidManager,  IOOptionBits(kIOHIDOptionsTypeNone) );

//limitations under the License.

import Foundation
import Carbon
import IOKit
import IOKit.usb
import IOKit.hid


struct IOKeyEventMonitorContext{
  var lastSeenSender:String
