private static final Controller[] enumerateControllers() {
   List controllers = new ArrayList();
   try {
     OSXHIDDeviceIterator it = new OSXHIDDeviceIterator();
     try {
       while (true) {
         OSXHIDDevice device;
         try {
           device = it.next();
           if (device == null) break;
           boolean device_used = false;
           try {
             int old_size = controllers.size();
             createControllersFromDevice(device, controllers);
             device_used = old_size != controllers.size();
           } catch (IOException e) {
             logln("Failed to create controllers from device: " + device.getProductName());
           }
           if (!device_used) device.release();
         } catch (IOException e) {
           logln("Failed to enumerate device: " + e.getMessage());
         }
       }
     } finally {
       it.close();
     }
   } catch (IOException e) {
     log("Failed to enumerate devices: " + e.getMessage());
     return new Controller[] {};
   }
   Controller[] controllers_array = new Controller[controllers.size()];
   controllers.toArray(controllers_array);
   return controllers_array;
 }
 private static final void createControllersFromDevice(OSXHIDDevice device, List controllers)
     throws IOException {
   UsagePair usage_pair = device.getUsagePair();
   if (usage_pair == null) return;
   List elements = device.getElements();
   if (usage_pair.getUsagePage() == UsagePage.GENERIC_DESKTOP
       && (usage_pair.getUsage() == GenericDesktopUsage.MOUSE
           || usage_pair.getUsage() == GenericDesktopUsage.POINTER)) {
     Controller mouse = createMouseFromDevice(device, elements);
     if (mouse != null) controllers.add(mouse);
   } else if (usage_pair.getUsagePage() == UsagePage.GENERIC_DESKTOP
       && (usage_pair.getUsage() == GenericDesktopUsage.KEYBOARD
           || usage_pair.getUsage() == GenericDesktopUsage.KEYPAD)) {
     Controller keyboard = createKeyboardFromDevice(device, elements);
     if (keyboard != null) controllers.add(keyboard);
   } else if (usage_pair.getUsagePage() == UsagePage.GENERIC_DESKTOP
       && usage_pair.getUsage() == GenericDesktopUsage.JOYSTICK) {
     Controller joystick = createControllerFromDevice(device, elements, Controller.Type.STICK);
     if (joystick != null) controllers.add(joystick);
   } else if (usage_pair.getUsagePage() == UsagePage.GENERIC_DESKTOP
       && usage_pair.getUsage() == GenericDesktopUsage.MULTI_AXIS_CONTROLLER) {
     Controller multiaxis = createControllerFromDevice(device, elements, Controller.Type.STICK);
     if (multiaxis != null) controllers.add(multiaxis);
   } else if (usage_pair.getUsagePage() == UsagePage.GENERIC_DESKTOP
       && usage_pair.getUsage() == GenericDesktopUsage.GAME_PAD) {
     Controller game_pad = createControllerFromDevice(device, elements, Controller.Type.GAMEPAD);
     if (game_pad != null) controllers.add(game_pad);
   }
 }
 private static final Keyboard createKeyboardFromDevice(OSXHIDDevice device, List elements)
     throws IOException {
   List components = new ArrayList();
   OSXHIDQueue queue = device.createQueue(AbstractController.EVENT_QUEUE_DEPTH);
   try {
     addElements(queue, elements, components, false);
   } catch (IOException e) {
     queue.release();
     throw e;
   }
   Component[] components_array = new Component[components.size()];
   components.toArray(components_array);
   Keyboard keyboard =
       new OSXKeyboard(device, queue, components_array, new Controller[] {}, new Rumbler[] {});
   return keyboard;
 }
 private static final AbstractController createControllerFromDevice(
     OSXHIDDevice device, List elements, Controller.Type type) throws IOException {
   List components = new ArrayList();
   OSXHIDQueue queue = device.createQueue(AbstractController.EVENT_QUEUE_DEPTH);
   try {
     addElements(queue, elements, components, false);
   } catch (IOException e) {
     queue.release();
     throw e;
   }
   Component[] components_array = new Component[components.size()];
   components.toArray(components_array);
   AbstractController controller =
       new OSXAbstractController(
           device, queue, components_array, new Controller[] {}, new Rumbler[] {}, type);
   return controller;
 }
 private static final Mouse createMouseFromDevice(OSXHIDDevice device, List elements)
     throws IOException {
   List components = new ArrayList();
   OSXHIDQueue queue = device.createQueue(AbstractController.EVENT_QUEUE_DEPTH);
   try {
     addElements(queue, elements, components, true);
   } catch (IOException e) {
     queue.release();
     throw e;
   }
   Component[] components_array = new Component[components.size()];
   components.toArray(components_array);
   Mouse mouse =
       new OSXMouse(device, queue, components_array, new Controller[] {}, new Rumbler[] {});
   if (mouse.getPrimaryButton() != null && mouse.getX() != null && mouse.getY() != null) {
     return mouse;
   } else {
     queue.release();
     return null;
   }
 }