Browse Source

Apple Remote : Update HIDRemote, fixes https://github.com/plexinc/plex-media-player-private/issues/669

Seems some newer version of HIDRemote was needed, tested on a 2010 macmini running High Sierra
Lionel CHAZALLON 6 years ago
parent
commit
a4be5c220a
2 changed files with 2023 additions and 1998 deletions
  1. 177 164
      external/HIDRemote/HIDRemote.h
  2. 1846 1834
      external/HIDRemote/HIDRemote.m

+ 177 - 164
external/HIDRemote/HIDRemote.h

@@ -1,32 +1,32 @@
 //
-//  HIDRemote.h
-//  HIDRemote V1.4 (18th February 2015)
+//  HIDRemote.m
+//  HIDRemote V1.6 (27th September 2017)
 //
 //  Created by Felix Schwarz on 06.04.07.
-//  Copyright 2007-2015 IOSPIRIT GmbH. All rights reserved.
+//  Copyright 2007-2017 IOSPIRIT GmbH. All rights reserved.
 //
 //  The latest version of this class is available at
 //     http://www.iospirit.com/developers/hidremote/
 //
 //  ** LICENSE *************************************************************************
 //
-//  Copyright (c) 2007-2014 IOSPIRIT GmbH (http://www.iospirit.com/)
+//  Copyright (c) 2007-2017 IOSPIRIT GmbH (http://www.iospirit.com/)
 //  All rights reserved.
-//  
+//
 //  Redistribution and use in source and binary forms, with or without modification,
 //  are permitted provided that the following conditions are met:
-//  
+//
 //  * Redistributions of source code must retain the above copyright notice, this list
 //    of conditions and the following disclaimer.
-//  
+//
 //  * Redistributions in binary form must reproduce the above copyright notice, this
 //    list of conditions and the following disclaimer in the documentation and/or other
 //    materials provided with the distribution.
-//  
+//
 //  * Neither the name of IOSPIRIT GmbH nor the names of its contributors may be used to
 //    endorse or promote products derived from this software without specific prior
 //    written permission.
-//  
+//
 //  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 //  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 //  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
@@ -40,7 +40,6 @@
 //
 //  ************************************************************************************
 
-
 //  ************************************************************************************
 //  ********************************** DOCUMENTATION ***********************************
 //  ************************************************************************************
@@ -67,6 +66,15 @@
 #include <Carbon/Carbon.h>
 #endif
 
+#ifndef HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING
+    #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
+        // Enable thread-safe notification handling by default if deploying to OS X >= 10.5
+        #define HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING 1
+    #else
+        #define HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING 0
+    #endif
+#endif
+
 #include <unistd.h>
 #include <mach/mach.h>
 #include <sys/types.h>
@@ -81,211 +89,213 @@
 #include <IOKit/hidsystem/IOHIDParameter.h>
 #include <IOKit/hidsystem/IOHIDShared.h>
 
-#pragma mark -- Enums / Codes  --
+#pragma mark - Enums / Codes
 
+#ifndef HID_REMOTE_MODE_ENUM
+#define HID_REMOTE_MODE_ENUM 1
 typedef enum
 {
-	kHIDRemoteModeNone = 0L,
-	kHIDRemoteModeShared,		// Share the remote with others - let's you listen to the remote control events as long as noone has an exclusive lock on it
-					// (RECOMMENDED ONLY FOR SPECIAL PURPOSES)
+    kHIDRemoteModeNone = 0L,
+    kHIDRemoteModeShared,		// Share the remote with others - let's you listen to the remote control events as long as noone has an exclusive lock on it
+                    // (RECOMMENDED ONLY FOR SPECIAL PURPOSES)
 
-	kHIDRemoteModeExclusive,	// Try to acquire an exclusive lock on the remote (NOT RECOMMENDED)
+    kHIDRemoteModeExclusive,	// Try to acquire an exclusive lock on the remote (NOT RECOMMENDED)
 
-	kHIDRemoteModeExclusiveAuto	// Try to acquire an exclusive lock on the remote whenever the application has focus. Temporarily release control over the
-					// remote when another application has focus (RECOMMENDED)
+    kHIDRemoteModeExclusiveAuto	// Try to acquire an exclusive lock on the remote whenever the application has focus. Temporarily release control over the
+                    // remote when another application has focus (RECOMMENDED)
 } HIDRemoteMode;
+#endif /* HID_REMOTE_MODE_ENUM */
 
 typedef enum
 {
-	/* A code reserved for "no button" (needed for tracking) */
-	kHIDRemoteButtonCodeNone	= 0L,
-
-	/* Standard codes - available for white plastic and aluminum remote */
-	kHIDRemoteButtonCodeUp,
-	kHIDRemoteButtonCodeDown,
-	kHIDRemoteButtonCodeLeft,
-	kHIDRemoteButtonCodeRight,
-	kHIDRemoteButtonCodeCenter,
-	kHIDRemoteButtonCodeMenu,
-
-	/* Extra codes - Only available for the new aluminum version of the remote */
-	kHIDRemoteButtonCodePlay,
-
-	/* Masks */
-	kHIDRemoteButtonCodeCodeMask      = 0xFFL,
-	kHIDRemoteButtonCodeHoldMask      = (1L << 16L),
-	kHIDRemoteButtonCodeSpecialMask   = (1L << 17L),
-	kHIDRemoteButtonCodeAluminumMask  = (1L << 21L), // PRIVATE - only used internally
-
-	/* Hold button standard codes - available for white plastic and aluminum remote */
-	kHIDRemoteButtonCodeUpHold       = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeUp),
-	kHIDRemoteButtonCodeDownHold     = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeDown),
-	kHIDRemoteButtonCodeLeftHold     = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeLeft),
-	kHIDRemoteButtonCodeRightHold    = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeRight),
-	kHIDRemoteButtonCodeCenterHold	 = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeCenter),
-	kHIDRemoteButtonCodeMenuHold	 = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeMenu),
-
-	/* Hold button extra codes - Only available for aluminum version of the remote */
-	kHIDRemoteButtonCodePlayHold	  = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodePlay),
-
-	/* DEPRECATED codes - compatibility with HIDRemote 1.0 */
-	kHIDRemoteButtonCodePlus	  = kHIDRemoteButtonCodeUp,
-	kHIDRemoteButtonCodePlusHold      = kHIDRemoteButtonCodeUpHold,
-	kHIDRemoteButtonCodeMinus	  = kHIDRemoteButtonCodeDown,
-	kHIDRemoteButtonCodeMinusHold     = kHIDRemoteButtonCodeDownHold,
-	kHIDRemoteButtonCodePlayPause	  = kHIDRemoteButtonCodeCenter,
-	kHIDRemoteButtonCodePlayPauseHold = kHIDRemoteButtonCodeCenterHold,
-
-	/* Special purpose codes */
-	kHIDRemoteButtonCodeIDChanged  = (kHIDRemoteButtonCodeSpecialMask|(1L << 18L)),	// (the ID of the connected remote has changed, you can safely ignore this)
-	#ifdef _HIDREMOTE_EXTENSIONS
-		#define _HIDREMOTE_EXTENSIONS_SECTION 1
-		#include "HIDRemoteAdditions.h"
-		#undef _HIDREMOTE_EXTENSIONS_SECTION
-	#endif /* _HIDREMOTE_EXTENSIONS */
+    /* A code reserved for "no button" (needed for tracking) */
+    kHIDRemoteButtonCodeNone	= 0L,
+
+    /* Standard codes - available for white plastic and aluminum remote */
+    kHIDRemoteButtonCodeUp,
+    kHIDRemoteButtonCodeDown,
+    kHIDRemoteButtonCodeLeft,
+    kHIDRemoteButtonCodeRight,
+    kHIDRemoteButtonCodeCenter,
+    kHIDRemoteButtonCodeMenu,
+
+    /* Extra codes - Only available for the new aluminum version of the remote */
+    kHIDRemoteButtonCodePlay,
+
+    /* Masks */
+    kHIDRemoteButtonCodeCodeMask      = 0xFFL,
+    kHIDRemoteButtonCodeHoldMask      = (1L << 16L),
+    kHIDRemoteButtonCodeSpecialMask   = (1L << 17L),
+    kHIDRemoteButtonCodeAluminumMask  = (1L << 21L), // PRIVATE - only used internally
+
+    /* Hold button standard codes - available for white plastic and aluminum remote */
+    kHIDRemoteButtonCodeUpHold       = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeUp),
+    kHIDRemoteButtonCodeDownHold     = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeDown),
+    kHIDRemoteButtonCodeLeftHold     = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeLeft),
+    kHIDRemoteButtonCodeRightHold    = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeRight),
+    kHIDRemoteButtonCodeCenterHold	 = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeCenter),
+    kHIDRemoteButtonCodeMenuHold	 = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodeMenu),
+
+    /* Hold button extra codes - Only available for aluminum version of the remote */
+    kHIDRemoteButtonCodePlayHold	  = (kHIDRemoteButtonCodeHoldMask|kHIDRemoteButtonCodePlay),
+
+    /* DEPRECATED codes - compatibility with HIDRemote 1.0 */
+    kHIDRemoteButtonCodePlus	  = kHIDRemoteButtonCodeUp,
+    kHIDRemoteButtonCodePlusHold      = kHIDRemoteButtonCodeUpHold,
+    kHIDRemoteButtonCodeMinus	  = kHIDRemoteButtonCodeDown,
+    kHIDRemoteButtonCodeMinusHold     = kHIDRemoteButtonCodeDownHold,
+    kHIDRemoteButtonCodePlayPause	  = kHIDRemoteButtonCodeCenter,
+    kHIDRemoteButtonCodePlayPauseHold = kHIDRemoteButtonCodeCenterHold,
+
+    /* Special purpose codes */
+    kHIDRemoteButtonCodeIDChanged  = (kHIDRemoteButtonCodeSpecialMask|(1L << 18L)),	// (the ID of the connected remote has changed, you can safely ignore this)
+    #ifdef _HIDREMOTE_EXTENSIONS
+        #define _HIDREMOTE_EXTENSIONS_SECTION 1
+        #include "HIDRemoteAdditions.h"
+        #undef _HIDREMOTE_EXTENSIONS_SECTION
+    #endif /* _HIDREMOTE_EXTENSIONS */
 } HIDRemoteButtonCode;
 
 typedef enum
 {
-	kHIDRemoteModelUndetermined = 0L,				// Assume a white plastic remote
-	kHIDRemoteModelWhitePlastic,					// Signal *likely* to be coming from a white plastic remote
-	kHIDRemoteModelAluminum						// Signal *definitely* coming from an aluminum remote
+    kHIDRemoteModelUndetermined = 0L,				// Assume a white plastic remote
+    kHIDRemoteModelWhitePlastic,					// Signal *likely* to be coming from a white plastic remote
+    kHIDRemoteModelAluminum						// Signal *definitely* coming from an aluminum remote
 } HIDRemoteModel;
 
 typedef enum
 {
-	kHIDRemoteAluminumRemoteSupportLevelNone = 0L,			// This system has no support for the Aluminum Remote at all
-	kHIDRemoteAluminumRemoteSupportLevelEmulation,			// This system possibly has support for the Aluminum Remote (via emulation)
-	kHIDRemoteAluminumRemoteSupportLevelNative			// This system has native support for the Aluminum Remote
+    kHIDRemoteAluminumRemoteSupportLevelNone = 0L,			// This system has no support for the Aluminum Remote at all
+    kHIDRemoteAluminumRemoteSupportLevelEmulation,			// This system possibly has support for the Aluminum Remote (via emulation)
+    kHIDRemoteAluminumRemoteSupportLevelNative			// This system has native support for the Aluminum Remote
 } HIDRemoteAluminumRemoteSupportLevel;
 
 @class HIDRemote;
 
-#pragma mark -- Delegate protocol (mandatory) --
+#pragma mark - Delegate protocol (mandatory)
 @protocol HIDRemoteDelegate
 
 // Notification of button events
 - (void)hidRemote:(HIDRemote *)hidRemote				// The instance of HIDRemote sending this
         eventWithButton:(HIDRemoteButtonCode)buttonCode			// Event for the button specified by code
-	isPressed:(BOOL)isPressed					// The button was pressed (YES) / released (NO)
-	fromHardwareWithAttributes:(NSMutableDictionary *)attributes;	// Information on the device this event comes from
+    isPressed:(BOOL)isPressed					// The button was pressed (YES) / released (NO)
+    fromHardwareWithAttributes:(NSMutableDictionary *)attributes;	// Information on the device this event comes from
 
 @optional
 
 // Notification of ID changes
 - (void)hidRemote:(HIDRemote *)hidRemote				// Invoked when the user switched to a remote control with a different ID
-	remoteIDChangedOldID:(SInt32)old
-	newID:(SInt32)newID
-	forHardwareWithAttributes:(NSMutableDictionary *)attributes;
+    remoteIDChangedOldID:(SInt32)old
+    newID:(SInt32)newID
+    forHardwareWithAttributes:(NSMutableDictionary *)attributes;
 
-// Notification about hardware additions/removals 
+// Notification about hardware additions/removals
 - (void)hidRemote:(HIDRemote *)hidRemote				// Invoked when new hardware was found / added to HIDRemote's pool
-	foundNewHardwareWithAttributes:(NSMutableDictionary *)attributes;
+    foundNewHardwareWithAttributes:(NSMutableDictionary *)attributes;
 
 - (void)hidRemote:(HIDRemote *)hidRemote				// Invoked when initialization of new hardware as requested failed
-	failedNewHardwareWithError:(NSError *)error;
+    failedNewHardwareWithError:(NSError *)error;
 
 - (void)hidRemote:(HIDRemote *)hidRemote				// Invoked when hardware was removed from HIDRemote's pool
-	releasedHardwareWithAttributes:(NSMutableDictionary *)attributes;
+    releasedHardwareWithAttributes:(NSMutableDictionary *)attributes;
 
 // ### WARNING: Unless you know VERY PRECISELY what you are doing, do not implement any of the delegate methods below. ###
 
 // Matching of newly found receiver hardware
 - (BOOL)hidRemote:(HIDRemote *)hidRemote				// Invoked when new hardware is inspected
-	inspectNewHardwareWithService:(io_service_t)service		// 
-	prematchResult:(BOOL)prematchResult;				// Return YES if HIDRemote should go on with this hardware and try
-									// to use it, or NO if it should not be persued further.
+    inspectNewHardwareWithService:(io_service_t)service		//
+    prematchResult:(BOOL)prematchResult;				// Return YES if HIDRemote should go on with this hardware and try
+                                    // to use it, or NO if it should not be persued further.
 
 // Exlusive lock lending
 - (BOOL)hidRemote:(HIDRemote *)hidRemote
-	lendExclusiveLockToApplicationWithInfo:(NSDictionary *)applicationInfo;
+    lendExclusiveLockToApplicationWithInfo:(NSDictionary *)applicationInfo;
 
 - (void)hidRemote:(HIDRemote *)hidRemote
-	exclusiveLockReleasedByApplicationWithInfo:(NSDictionary *)applicationInfo;
+    exclusiveLockReleasedByApplicationWithInfo:(NSDictionary *)applicationInfo;
 
 - (BOOL)hidRemote:(HIDRemote *)hidRemote
-	shouldRetryExclusiveLockWithInfo:(NSDictionary *)applicationInfo;
-
-@end 
+    shouldRetryExclusiveLockWithInfo:(NSDictionary *)applicationInfo;
 
+@end
 
-#pragma mark -- Actual header file for class  --
 
+#pragma mark - Actual header file for class
 @interface HIDRemote : NSObject
 {
-	// IOMasterPort
-	mach_port_t _masterPort;
-
-	// Notification ports
-	IONotificationPortRef _notifyPort;
-	CFRunLoopSourceRef _notifyRLSource;
-	
-	// Matching iterator
-	io_iterator_t _matchingServicesIterator;
-	
-	// SecureInput notification
-	io_object_t _secureInputNotification;
-	
-	// Service attributes
-	NSMutableDictionary *_serviceAttribMap;
-	
-	// Mode
-	HIDRemoteMode _mode;
-	BOOL _autoRecover;
-	NSTimer *_autoRecoveryTimer;
-	
-	// Delegate
-	NSObject <HIDRemoteDelegate> *_delegate;
-	
-	// Last seen ID and remote model
-	SInt32 _lastSeenRemoteID;
-	HIDRemoteModel _lastSeenModel;
-	SInt32 _lastSeenModelRemoteID;
-	
-	// Unused button codes
-	NSArray *_unusedButtonCodes;
-	
-	// Simulate Plus/Minus Hold
-	BOOL _simulateHoldEvents;
-	
-	// SecureEventInput workaround
-	BOOL _secureEventInputWorkAround;
-	UInt64 _lastSecureEventInputPIDSum;
-	uid_t _lastFrontUserSession;
-	BOOL _lastScreenIsLocked;
-	
-	// Exclusive lock lending
-	BOOL _exclusiveLockLending;
-	BOOL _sendExclusiveResourceReuseNotification;
-	NSNumber *_waitForReturnByPID;
-	NSNumber *_returnToPID;
-	BOOL _isRestarting;
-	
-	// Status notifications
-	BOOL _sendStatusNotifications;
-	NSString *_pidString;
-	
-	// Status
-	BOOL _applicationIsTerminating;
-	BOOL _isStopping;
-	
-	// Thread safety
-	#ifdef HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING /* #define HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING if you're running your HIDRemote instance on a background thread (requires OS X 10.5 or later) */
-	NSThread *_runOnThread;
-	#endif
+    // IOMasterPort
+    mach_port_t _masterPort;
+
+    // Notification ports
+    IONotificationPortRef _notifyPort;
+    CFRunLoopSourceRef _notifyRLSource;
+
+    // Matching iterator
+    io_iterator_t _matchingServicesIterator;
+
+    // SecureInput notification
+    io_object_t _secureInputNotification;
+
+    // Service attributes
+    NSMutableDictionary *_serviceAttribMap;
+
+    // Mode
+    HIDRemoteMode _mode;
+    BOOL _autoRecover;
+    NSTimer *_autoRecoveryTimer;
+
+    // Delegate
+    NSObject <HIDRemoteDelegate> *_delegate;
+
+    // Last seen ID and remote model
+    SInt32 _lastSeenRemoteID;
+    HIDRemoteModel _lastSeenModel;
+    SInt32 _lastSeenModelRemoteID;
+
+    // Unused button codes
+    NSArray *_unusedButtonCodes;
+
+    // Simulate Plus/Minus Hold
+    BOOL _simulateHoldEvents;
+
+    // SecureEventInput workaround
+    BOOL _secureEventInputWorkAround;
+    UInt64 _lastSecureEventInputPIDSum;
+    uid_t _lastFrontUserSession;
+    BOOL _lastScreenIsLocked;
+
+    // Exclusive lock lending
+    BOOL _exclusiveLockLending;
+    BOOL _sendExclusiveResourceReuseNotification;
+    NSNumber *_waitForReturnByPID;
+    NSNumber *_returnToPID;
+    BOOL _isRestarting;
+
+    // Status notifications
+    BOOL _sendStatusNotifications;
+    NSString *_pidString;
+
+    // Status
+    BOOL _applicationIsTerminating;
+    BOOL _isStopping;
+
+    // Thread safety
+    #if HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING /* #define HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING if you're running your HIDRemote instance on a background thread (requires OS X 10.5 or later) */
+    NSThread *_runOnThread;
+    #endif
 }
 
-#pragma mark -- PUBLIC: Shared HID Remote --
+#pragma mark - PUBLIC: Shared HID Remote
 + (HIDRemote *)sharedHIDRemote;
 
-#pragma mark -- PUBLIC: System Information --
+#pragma mark - PUBLIC: System Information
 + (BOOL)isCandelairInstalled;
 + (BOOL)isCandelairInstallationRequiredForRemoteMode:(HIDRemoteMode)remoteMode;
 + (SInt32)OSXVersion;
 - (HIDRemoteAluminumRemoteSupportLevel)aluminiumRemoteSystemSupportLevel;
 
-#pragma mark -- PUBLIC: Interface / API --
-- (BOOL)startRemoteControl:(HIDRemoteMode)hidRemoteMode;	
+#pragma mark - PUBLIC: Interface / API
+- (BOOL)startRemoteControl:(HIDRemoteMode)hidRemoteMode;
 - (void)stopRemoteControl;
 
 - (BOOL)isStarted;
@@ -307,7 +317,7 @@ typedef enum
 - (void)setUnusedButtonCodes:(NSArray *)newArrayWithUnusedButtonCodesAsNSNumbers;
 - (NSArray *)unusedButtonCodes;
 
-#pragma mark -- PUBLIC: Expert APIs --
+#pragma mark - PUBLIC: Expert APIs
 - (void)setEnableSecureEventInputWorkaround:(BOOL)newEnableSecureEventInputWorkaround;
 - (BOOL)enableSecureEventInputWorkaround;
 
@@ -317,28 +327,28 @@ typedef enum
 - (BOOL)isApplicationTerminating;
 - (BOOL)isStopping;
 
-#pragma mark -- PRIVATE: HID Event handling --
+#pragma mark - PRIVATE: HID Event handling
 - (void)_handleButtonCode:(HIDRemoteButtonCode)buttonCode isPressed:(BOOL)isPressed hidAttribsDict:(NSMutableDictionary *)hidAttribsDict;
 - (void)_sendButtonCode:(HIDRemoteButtonCode)buttonCode isPressed:(BOOL)isPressed hidAttribsDict:(NSMutableDictionary *)hidAttribsDict;
 - (void)_hidEventFor:(io_service_t)hidDevice from:(IOHIDQueueInterface **)interface withResult:(IOReturn)result;
 
-#pragma mark -- PRIVATE: Service setup and destruction --
+#pragma mark - PRIVATE: Service setup and destruction
 - (BOOL)_prematchService:(io_object_t)service;
 - (HIDRemoteButtonCode)buttonCodeForUsage:(unsigned int)usage usagePage:(unsigned int)usagePage;
 - (BOOL)_setupService:(io_object_t)service;
 - (void)_destructService:(io_object_t)service;
 
-#pragma mark -- PRIVATE: Distributed notifiations handling --
+#pragma mark - PRIVATE: Distributed notifiations handling
 - (void)_postStatusWithAction:(NSString *)action;
 - (void)_handleNotifications:(NSNotification *)notification;
 - (void)_setSendStatusNotifications:(BOOL)doSend;
 - (BOOL)_sendStatusNotifications;
 
-#pragma mark -- PRIVATE: Application becomes active / inactive handling for kHIDRemoteModeExclusiveAuto --
+#pragma mark - PRIVATE: Application becomes active / inactive handling for kHIDRemoteModeExclusiveAuto
 - (void)_appStatusChanged:(NSNotification *)notification;
 - (void)_delayedAutoRecovery:(NSTimer *)aTimer;
 
-#pragma mark -- PRIVATE: Notification handling --
+#pragma mark - PRIVATE: Notification handling
 - (void)_serviceMatching:(io_iterator_t)iterator;
 - (void)_serviceNotificationFor:(io_service_t)service messageType:(natural_t)messageType messageArgument:(void *)messageArgument;
 - (void)_updateSessionInformation;
@@ -346,12 +356,12 @@ typedef enum
 
 @end
 
-#pragma mark -- Information attribute keys --
+#pragma mark - Information attribute keys
 extern NSString *kHIDRemoteManufacturer;
 extern NSString *kHIDRemoteProduct;
 extern NSString *kHIDRemoteTransport;
 
-#pragma mark -- Internal/Expert attribute keys (AKA: don't touch these unless you really, really, REALLY know what you do) --
+#pragma mark - Internal/Expert attribute keys (AKA: don't touch these unless you really, really, REALLY know what you do)
 extern NSString *kHIDRemoteCFPluginInterface;
 extern NSString *kHIDRemoteHIDDeviceInterface;
 extern NSString *kHIDRemoteCookieButtonCodeLUT;
@@ -365,14 +375,14 @@ extern NSString *kHIDRemoteSimulateHoldEventsOriginButtonCode;
 extern NSString *kHIDRemoteAluminumRemoteSupportLevel;
 extern NSString *kHIDRemoteAluminumRemoteSupportOnDemand;
 
-#pragma mark -- Distributed notifications --
+#pragma mark - Distributed notifications
 extern NSString *kHIDRemoteDNHIDRemotePing;
 extern NSString *kHIDRemoteDNHIDRemoteRetry;
 extern NSString *kHIDRemoteDNHIDRemoteStatus;
 
 extern NSString *kHIDRemoteDNHIDRemoteRetryGlobalObject;
 
-#pragma mark -- Distributed notifications userInfo keys and values --
+#pragma mark - Distributed notifications userInfo keys and values
 extern NSString *kHIDRemoteDNStatusHIDRemoteVersionKey;
 extern NSString *kHIDRemoteDNStatusPIDKey;
 extern NSString *kHIDRemoteDNStatusModeKey;
@@ -385,8 +395,11 @@ extern NSString *kHIDRemoteDNStatusActionStop;
 extern NSString *kHIDRemoteDNStatusActionUpdate;
 extern NSString *kHIDRemoteDNStatusActionNoNeed;
 
-#pragma mark -- Driver compatibility flags --
+#pragma mark - Driver compatibility flags
+#ifndef HID_REMOTE_COMPATIBILITY_FLAGS_ENUM
+#define HID_REMOTE_COMPATIBILITY_FLAGS_ENUM 1
 typedef enum
 {
-	kHIDRemoteCompatibilityFlagsStandardHIDRemoteDevice = 1L,
+    kHIDRemoteCompatibilityFlagsStandardHIDRemoteDevice = 1L,
 } HIDRemoteCompatibilityFlags;
+#endif /* HID_REMOTE_COMPATIBILITY_FLAGS_ENUM */

+ 1846 - 1834
external/HIDRemote/HIDRemote.m

@@ -1,32 +1,32 @@
 //
 //  HIDRemote.m
-//  HIDRemote V1.4 (18th February 2015)
+//  HIDRemote V1.6 (27th September 2017)
 //
 //  Created by Felix Schwarz on 06.04.07.
-//  Copyright 2007-2015 IOSPIRIT GmbH. All rights reserved.
+//  Copyright 2007-2017 IOSPIRIT GmbH. All rights reserved.
 //
 //  The latest version of this class is available at
 //     http://www.iospirit.com/developers/hidremote/
 //
 //  ** LICENSE *************************************************************************
 //
-//  Copyright (c) 2007-2014 IOSPIRIT GmbH (http://www.iospirit.com/)
+//  Copyright (c) 2007-2017 IOSPIRIT GmbH (http://www.iospirit.com/)
 //  All rights reserved.
-//  
+//
 //  Redistribution and use in source and binary forms, with or without modification,
 //  are permitted provided that the following conditions are met:
-//  
+//
 //  * Redistributions of source code must retain the above copyright notice, this list
 //    of conditions and the following disclaimer.
-//  
+//
 //  * Redistributions in binary form must reproduce the above copyright notice, this
 //    list of conditions and the following disclaimer in the documentation and/or other
 //    materials provided with the distribution.
-//  
+//
 //  * Neither the name of IOSPIRIT GmbH nor the names of its contributors may be used to
 //    endorse or promote products derived from this software without specific prior
 //    written permission.
-//  
+//
 //  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 //  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 //  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
@@ -51,24 +51,55 @@
 
 #import "HIDRemote.h"
 
+// ARC support
+#if !__has_feature(objc_arc)
+    #define HIDRemoteRetain(object)       [object retain]
+    #define HIDRemoteRetained(object)     [object retain]
+    #define HIDRemoteRelease(object)      [object release]
+    #define HIDRemoteReleaseNil(object)   [object release]; object=nil
+    #define HIDRemoteAutoreleased(object) [object autorelease]
+    #define HIDRemoteSuperDealloc(object) [super dealloc]
+
+    #define HIDRemoteAutoreleasePoolOpen() NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    #define HIDRemoteAutoreleasePoolClose() [pool release];
+
+    #define __HIDRemoteBridge
+    #define HIDRemoteBridgingRelease
+    #define HIDRemoteBridgingRetain
+#else /* !__has_feature(objc_arc) */
+    #define HIDRemoteRetain(object)
+    #define HIDRemoteRetained(object)     object
+    #define HIDRemoteRelease(object)
+    #define HIDRemoteReleaseNil(object)   object=nil
+    #define HIDRemoteAutoreleased(object) object
+    #define HIDRemoteSuperDealloc(object)
+
+    #define HIDRemoteAutoreleasePoolOpen()  @autoreleasepool {
+    #define HIDRemoteAutoreleasePoolClose() }
+
+    #define __HIDRemoteBridge		  __bridge
+    #define HIDRemoteBridgingRelease	 CFBridgingRelease
+    #define HIDRemoteBridgingRetain	 CFBridgingRetain
+#endif
+
 // Callback Prototypes
-static void HIDEventCallback(	void * target, 
-				IOReturn result,
-				void * refCon,
-				void * sender);
+static void HIDEventCallback(	void * target,
+                IOReturn result,
+                void * refcon,
+                void * sender);
 
 static void ServiceMatchingCallback(	void *refCon,
-					io_iterator_t iterator);
+                    io_iterator_t iterator);
 
 static void ServiceNotificationCallback(void *		refCon,
-					io_service_t 	service,
-					natural_t 	messageType,
-					void *		messageArgument);
+                    io_service_t 	service,
+                    natural_t 	messageType,
+                    void *		messageArgument);
 
 static void SecureInputNotificationCallback(	void *		refCon,
-						io_service_t 	service,
-						natural_t 	messageType,
-						void *		messageArgument);
+                        io_service_t 	service,
+                        natural_t 	messageType,
+                        void *		messageArgument);
 
 // Shared HIDRemote instance
 static HIDRemote *sHIDRemote = nil;
@@ -79,2062 +110,2043 @@ static HIDRemote *sHIDRemote = nil;
 
 + (HIDRemote *)sharedHIDRemote
 {
-	if (sHIDRemote==nil)
-	{
-		sHIDRemote = [[HIDRemote alloc] init];
-	}
-	
-	return (sHIDRemote);
+    if (sHIDRemote==nil)
+    {
+        sHIDRemote = [[HIDRemote alloc] init];
+    }
+
+    return (sHIDRemote);
 }
 
 - (id)init
 {
-	if ((self = [super init]) != nil)
-	{
-		#ifdef HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING
-		_runOnThread = [[NSThread currentThread] retain];
-		#endif
-	
-		// Detect application becoming active/inactive
-		[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_appStatusChanged:)	 name:NSApplicationDidBecomeActiveNotification	object:[NSApplication sharedApplication]];
-		[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_appStatusChanged:)	 name:NSApplicationWillResignActiveNotification object:[NSApplication sharedApplication]];
-		[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_appStatusChanged:)	 name:NSApplicationWillTerminateNotification	object:[NSApplication sharedApplication]];
-
-		// Handle distributed notifications
-		_pidString = [[NSString alloc] initWithFormat:@"%d", getpid()];
-		
-		[[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleNotifications:) name:kHIDRemoteDNHIDRemotePing	object:nil];
-		[[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleNotifications:) name:kHIDRemoteDNHIDRemoteRetry	object:kHIDRemoteDNHIDRemoteRetryGlobalObject];
-		[[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleNotifications:) name:kHIDRemoteDNHIDRemoteRetry	object:_pidString];
-
-		// Enabled by default: simulate hold events for plus/minus
-		_simulateHoldEvents = YES;
-		
-		// Enabled by default: work around for a locking issue introduced with Security Update 2008-004 / 10.4.9 and beyond (credit for finding this workaround goes to Martin Kahr)
-		_secureEventInputWorkAround = YES;
-		_secureInputNotification = 0;
-		
-		// Initialize instance variables
-		_lastSeenRemoteID = -1;
-		_lastSeenModel = kHIDRemoteModelUndetermined;
-		_unusedButtonCodes = [[NSMutableArray alloc] init];
-		_exclusiveLockLending = NO;
-		_sendExclusiveResourceReuseNotification = YES;
-		_applicationIsTerminating = NO;
-		
-		// Send status notifications
-		_sendStatusNotifications = YES;
-	}
-
-	return (self);
+    if ((self = [super init]) != nil)
+    {
+        #if HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING
+        _runOnThread = HIDRemoteRetained([NSThread currentThread]);
+        #endif
+
+        // Detect application becoming active/inactive
+        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_appStatusChanged:)	 name:NSApplicationDidBecomeActiveNotification	object:[NSApplication sharedApplication]];
+        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_appStatusChanged:)	 name:NSApplicationWillResignActiveNotification object:[NSApplication sharedApplication]];
+        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_appStatusChanged:)	 name:NSApplicationWillTerminateNotification	object:[NSApplication sharedApplication]];
+
+        // Handle distributed notifications
+        _pidString = [[NSString alloc] initWithFormat:@"%d", getpid()];
+
+        [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleNotifications:) name:kHIDRemoteDNHIDRemotePing	object:nil];
+        [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleNotifications:) name:kHIDRemoteDNHIDRemoteRetry	object:kHIDRemoteDNHIDRemoteRetryGlobalObject];
+        [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleNotifications:) name:kHIDRemoteDNHIDRemoteRetry	object:_pidString];
+
+        // Enabled by default: simulate hold events for plus/minus
+        _simulateHoldEvents = YES;
+
+        // Enabled by default: work around for a locking issue introduced with Security Update 2008-004 / 10.4.9 and beyond (credit for finding this workaround goes to Martin Kahr)
+        _secureEventInputWorkAround = YES;
+        _secureInputNotification = 0;
+
+        // Initialize instance variables
+        _lastSeenRemoteID = -1;
+        _lastSeenModel = kHIDRemoteModelUndetermined;
+        _unusedButtonCodes = [[NSMutableArray alloc] init];
+        _exclusiveLockLending = NO;
+        _sendExclusiveResourceReuseNotification = YES;
+        _applicationIsTerminating = NO;
+
+        // Send status notifications
+        _sendStatusNotifications = YES;
+    }
+
+    return (self);
 }
 
 - (void)dealloc
 {
-	[[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationWillTerminateNotification object:[NSApplication sharedApplication]];
-	[[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationWillResignActiveNotification object:[NSApplication sharedApplication]];
-	[[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationDidBecomeActiveNotification object:[NSApplication sharedApplication]];
+    [[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationWillTerminateNotification object:[NSApplication sharedApplication]];
+    [[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationWillResignActiveNotification object:[NSApplication sharedApplication]];
+    [[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationDidBecomeActiveNotification object:[NSApplication sharedApplication]];
 
-	[[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kHIDRemoteDNHIDRemotePing  object:nil];
-	[[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kHIDRemoteDNHIDRemoteRetry object:kHIDRemoteDNHIDRemoteRetryGlobalObject];
-	[[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kHIDRemoteDNHIDRemoteRetry object:_pidString];
-	[[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:nil object:nil]; /* As demanded by the documentation for -[NSDistributedNotificationCenter removeObserver:name:object:] */
-	
-	[self stopRemoteControl];
+    [[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kHIDRemoteDNHIDRemotePing  object:nil];
+    [[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kHIDRemoteDNHIDRemoteRetry object:kHIDRemoteDNHIDRemoteRetryGlobalObject];
+    [[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kHIDRemoteDNHIDRemoteRetry object:_pidString];
+    [[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:nil object:nil]; /* As demanded by the documentation for -[NSDistributedNotificationCenter removeObserver:name:object:] */
 
-	[self setExclusiveLockLendingEnabled:NO];
+    [self stopRemoteControl];
 
-	[self setDelegate:nil];
+    [self setExclusiveLockLendingEnabled:NO];
 
-	if (_unusedButtonCodes != nil)
-	{
-		[_unusedButtonCodes release];
-		_unusedButtonCodes = nil;
-	}
+    [self setDelegate:nil];
 
-	#ifdef HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING
-	[_runOnThread release];
-	_runOnThread = nil;
-	#endif
+    if (_unusedButtonCodes != nil)
+    {
+        HIDRemoteReleaseNil(_unusedButtonCodes);
+    }
 
-	[_pidString release];
-	_pidString = nil;
+    #if HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING
+    HIDRemoteReleaseNil(_runOnThread);
+    #endif
 
-	[super dealloc];
+    HIDRemoteReleaseNil(_pidString);
+
+    HIDRemoteSuperDealloc();
 }
 
 #pragma mark - PUBLIC: System Information
 + (BOOL)isCandelairInstalled
 {
-	mach_port_t	masterPort = 0;
-	kern_return_t	kernResult;
-	io_service_t	matchingService = 0;
-	BOOL isInstalled = NO;
+    mach_port_t	masterPort = 0;
+    kern_return_t	kernResult;
+    io_service_t	matchingService = 0;
+    BOOL isInstalled = NO;
 
-	kernResult = IOMasterPort(MACH_PORT_NULL, &masterPort);
-	if ((kernResult!=kIOReturnSuccess) || (masterPort==0)) { return(NO); }
+    kernResult = IOMasterPort(MACH_PORT_NULL, &masterPort);
+    if ((kernResult!=kIOReturnSuccess) || (masterPort==0)) { return(NO); }
 
-	if ((matchingService = IOServiceGetMatchingService(masterPort, IOServiceMatching("IOSPIRITIRController"))) != 0)
-	{
-		isInstalled = YES;
-		IOObjectRelease((io_object_t) matchingService);
-	}
+    if ((matchingService = IOServiceGetMatchingService(masterPort, IOServiceMatching("IOSPIRITIRController"))) != 0)
+    {
+        isInstalled = YES;
+        IOObjectRelease((io_object_t) matchingService);
+    }
 
-	mach_port_deallocate(mach_task_self(), masterPort);
+    mach_port_deallocate(mach_task_self(), masterPort);
 
-	return (isInstalled);
+    return (isInstalled);
 }
 
 + (BOOL)isCandelairInstallationRequiredForRemoteMode:(HIDRemoteMode)remoteMode
 {
-	// Determine OS version
-	switch ([self OSXVersion])
-	{
-		case 0x1060: // OS 10.6
-		case 0x1061: // OS 10.6.1
-			// OS X 10.6(.0) and OS X 10.6.1 require the Candelair driver for to be installed,
-			// so that third party apps can acquire an exclusive lock on the receiver HID Device
-			// via IOKit.
-
-			switch (remoteMode)
-			{
-				case kHIDRemoteModeExclusive:
-				case kHIDRemoteModeExclusiveAuto:
-					if (![self isCandelairInstalled])
-					{
-						return (YES);
-					}
-				break;
-				
-				default:
-					return (NO);
-				break;
-			}
-		break;
-	}
-	
-	return (NO);
+    // Determine OS version
+    switch ([self OSXVersion])
+    {
+        case 0x1060: // OS 10.6
+        case 0x1061: // OS 10.6.1
+            // OS X 10.6(.0) and OS X 10.6.1 require the Candelair driver for to be installed,
+            // so that third party apps can acquire an exclusive lock on the receiver HID Device
+            // via IOKit.
+
+            switch (remoteMode)
+            {
+                case kHIDRemoteModeExclusive:
+                case kHIDRemoteModeExclusiveAuto:
+                    if (![self isCandelairInstalled])
+                    {
+                        return (YES);
+                    }
+                break;
+
+                default:
+                    return (NO);
+                break;
+            }
+        break;
+    }
+
+    return (NO);
 }
 
 // Drop-in replacement for Gestalt(gestaltSystemVersion, &osXVersion) that avoids use of Gestalt for code targeting 10.10 or later
 + (SInt32)OSXVersion
 {
-	static SInt32 sHRGestaltOSXVersion = 0;
-
-	if (sHRGestaltOSXVersion==0)
-	{
-		#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_9
-		// Code for builds targeting OS X 10.10+
-		NSOperatingSystemVersion osVersion;
-
-		osVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
-		
-		sHRGestaltOSXVersion = (SInt32)(0x01000 | ((osVersion.majorVersion-10)<<8) | (osVersion.minorVersion<<4) | osVersion.patchVersion);
-		#else
-			#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_9
-			// Code for builds using the OS X 10.10 SDK or later
-			NSOperatingSystemVersion osVersion;
-
-			if ([[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)])
-			{
-				osVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
-				
-				sHRGestaltOSXVersion = (SInt32)(0x01000 | ((osVersion.majorVersion-10)<<8) | (osVersion.minorVersion<<4) | osVersion.patchVersion);
-			}
-			else
-			{
-				#pragma clang diagnostic push
-				#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-				Gestalt (gestaltSystemVersion, &sHRGestaltOSXVersion);
-				#pragma clang diagnostic pop
-			}
-			#else /* MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_9 */
-				// Code for builds using an SDK older than 10.10
-				#pragma clang diagnostic push
-				#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-				Gestalt (gestaltSystemVersion, &sHRGestaltOSXVersion);
-				#pragma clang diagnostic pop
-			#endif /* MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_9 */
-		#endif /*  MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_9 */
-	}
-	
-	return (sHRGestaltOSXVersion);
+    static SInt32 sHRGestaltOSXVersion = 0;
+
+    if (sHRGestaltOSXVersion==0)
+    {
+        #if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_9
+        // Code for builds targeting OS X 10.10+
+        NSOperatingSystemVersion osVersion;
+
+        osVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
+
+        sHRGestaltOSXVersion = (SInt32)(0x01000 | ((osVersion.majorVersion-10)<<8) | (osVersion.minorVersion<<4) | osVersion.patchVersion);
+        #else
+            #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_9
+            // Code for builds using the OS X 10.10 SDK or later
+            NSOperatingSystemVersion osVersion;
+
+            if ([[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)])
+            {
+                osVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
+
+                sHRGestaltOSXVersion = (SInt32)(0x01000 | ((osVersion.majorVersion-10)<<8) | (osVersion.minorVersion<<4) | osVersion.patchVersion);
+            }
+            else
+            {
+                #pragma clang diagnostic push
+                #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+                Gestalt (gestaltSystemVersion, &sHRGestaltOSXVersion);
+                #pragma clang diagnostic pop
+            }
+            #else /* MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_9 */
+                // Code for builds using an SDK older than 10.10
+                #pragma clang diagnostic push
+                #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+                Gestalt (gestaltSystemVersion, &sHRGestaltOSXVersion);
+                #pragma clang diagnostic pop
+            #endif /* MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_9 */
+        #endif /*  MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_9 */
+    }
+
+    return (sHRGestaltOSXVersion);
 }
 
 - (HIDRemoteAluminumRemoteSupportLevel)aluminiumRemoteSystemSupportLevel
 {
-	HIDRemoteAluminumRemoteSupportLevel supportLevel = kHIDRemoteAluminumRemoteSupportLevelNone;
-	NSEnumerator *attribDictsEnum;
-	NSDictionary *hidAttribsDict;
-	
-	attribDictsEnum = [_serviceAttribMap objectEnumerator];
-	
-	while ((hidAttribsDict = [attribDictsEnum nextObject]) != nil)
-	{
-		NSNumber *deviceSupportLevel;
-		
-		if ((deviceSupportLevel = [hidAttribsDict objectForKey:kHIDRemoteAluminumRemoteSupportLevel]) != nil)
-		{
-			if ([deviceSupportLevel intValue] > (int)supportLevel)
-			{
-				supportLevel = [deviceSupportLevel intValue];
-			}
-		}
-	}
-	
-	return (supportLevel);
+    HIDRemoteAluminumRemoteSupportLevel supportLevel = kHIDRemoteAluminumRemoteSupportLevelNone;
+    NSEnumerator *attribDictsEnum;
+    NSDictionary *hidAttribsDict;
+
+    attribDictsEnum = [_serviceAttribMap objectEnumerator];
+
+    while ((hidAttribsDict = [attribDictsEnum nextObject]) != nil)
+    {
+        NSNumber *deviceSupportLevel;
+
+        if ((deviceSupportLevel = [hidAttribsDict objectForKey:kHIDRemoteAluminumRemoteSupportLevel]) != nil)
+        {
+            if ([deviceSupportLevel intValue] > (int)supportLevel)
+            {
+                supportLevel = [deviceSupportLevel intValue];
+            }
+        }
+    }
+
+    return (supportLevel);
 }
 
 #pragma mark - PUBLIC: Interface / API
 - (BOOL)startRemoteControl:(HIDRemoteMode)hidRemoteMode
 {
-	if ((_mode == kHIDRemoteModeNone) && (hidRemoteMode != kHIDRemoteModeNone))
-	{
-		kern_return_t		kernReturn;
-		CFMutableDictionaryRef	matchDict=NULL;
-		io_service_t rootService;
-		
-		do
-		{
-			// Get IOKit master port
-			kernReturn = IOMasterPort(bootstrap_port, &_masterPort);
-			if ((kernReturn!=kIOReturnSuccess) || (_masterPort==0)) { break; }
-					
-			// Setup notification port
-			_notifyPort = IONotificationPortCreate(_masterPort);
-			
-			if ((_notifyRLSource = IONotificationPortGetRunLoopSource(_notifyPort)) != NULL)
-			{
-				CFRunLoopAddSource(	CFRunLoopGetCurrent(),
-							_notifyRLSource,
-							kCFRunLoopCommonModes);
-			}
-			else
-			{
-				break;
-			}
-			
-			// Setup SecureInput notification
-			if ((hidRemoteMode == kHIDRemoteModeExclusive) || (hidRemoteMode == kHIDRemoteModeExclusiveAuto))
-			{
-				if ((rootService = IORegistryEntryFromPath(_masterPort, kIOServicePlane ":/")) != 0)
-				{
-					kernReturn = IOServiceAddInterestNotification(	_notifyPort,
-											rootService,
-											kIOBusyInterest,
-											SecureInputNotificationCallback,
-											(void *)self,
-											&_secureInputNotification);
-					if (kernReturn != kIOReturnSuccess) { break; }
-					
-					[self _updateSessionInformation];
-				}
-				else
-				{
-					break;
-				}
-			}
-
-			// Setup notification matching dict
-			matchDict = IOServiceMatching(kIOHIDDeviceKey);
-			CFRetain(matchDict);
-
-			// Actually add notification
-			kernReturn = IOServiceAddMatchingNotification(	_notifyPort,
-									kIOFirstMatchNotification,
-									matchDict,			// one reference count consumed by this call
-									ServiceMatchingCallback,
-									(void *) self,
-									&_matchingServicesIterator);
-			if (kernReturn != kIOReturnSuccess) { break; }
-
-			// Setup serviceAttribMap 
-			_serviceAttribMap = [[NSMutableDictionary alloc] init];
-			if (_serviceAttribMap==nil) { break; }
-			
-			// Phew .. everything went well!
-			_mode = hidRemoteMode;
-			CFRelease(matchDict);
-			
-			[self _serviceMatching:_matchingServicesIterator];
-			
-			[self _postStatusWithAction:kHIDRemoteDNStatusActionStart];
-			
-			// Register for system wake notifications
-			[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(_computerDidWake:) name:NSWorkspaceDidWakeNotification object:nil];
-			
-			return (YES);
-
-		}while(0);
-		
-		// An error occured. Do necessary clean up.
-		if (matchDict!=NULL)
-		{
-			CFRelease(matchDict);
-			matchDict = NULL;
-		}
-		
-		[self stopRemoteControl];
-	}
-		
-	return (NO);
+    if ((_mode == kHIDRemoteModeNone) && (hidRemoteMode != kHIDRemoteModeNone))
+    {
+        kern_return_t		kernReturn;
+        CFMutableDictionaryRef	matchDict=NULL;
+        io_service_t rootService;
+
+        do
+        {
+            // Get IOKit master port
+            kernReturn = IOMasterPort(bootstrap_port, &_masterPort);
+            if ((kernReturn!=kIOReturnSuccess) || (_masterPort==0)) { break; }
+
+            // Setup notification port
+            _notifyPort = IONotificationPortCreate(_masterPort);
+
+            if ((_notifyRLSource = IONotificationPortGetRunLoopSource(_notifyPort)) != NULL)
+            {
+                CFRunLoopAddSource(	CFRunLoopGetCurrent(),
+                            _notifyRLSource,
+                            kCFRunLoopCommonModes);
+            }
+            else
+            {
+                break;
+            }
+
+            // Setup SecureInput notification
+            if ((hidRemoteMode == kHIDRemoteModeExclusive) || (hidRemoteMode == kHIDRemoteModeExclusiveAuto))
+            {
+                if ((rootService = IORegistryEntryFromPath(_masterPort, kIOServicePlane ":/")) != 0)
+                {
+                    kernReturn = IOServiceAddInterestNotification(	_notifyPort,
+                                            rootService,
+                                            kIOBusyInterest,
+                                            SecureInputNotificationCallback,
+                                            (__HIDRemoteBridge void *)self,
+                                            &_secureInputNotification);
+                    if (kernReturn != kIOReturnSuccess) { break; }
+
+                    [self _updateSessionInformation];
+                }
+                else
+                {
+                    break;
+                }
+            }
+
+            // Setup notification matching dict
+            matchDict = IOServiceMatching(kIOHIDDeviceKey);
+            CFRetain(matchDict);
+
+            // Actually add notification
+            kernReturn = IOServiceAddMatchingNotification(	_notifyPort,
+                                    kIOFirstMatchNotification,
+                                    matchDict,			// one reference count consumed by this call
+                                    ServiceMatchingCallback,
+                                    (__HIDRemoteBridge void *) self,
+                                    &_matchingServicesIterator);
+            if (kernReturn != kIOReturnSuccess) { break; }
+
+            // Setup serviceAttribMap
+            _serviceAttribMap = [[NSMutableDictionary alloc] init];
+            if (_serviceAttribMap==nil) { break; }
+
+            // Phew .. everything went well!
+            _mode = hidRemoteMode;
+            CFRelease(matchDict);
+
+            [self _serviceMatching:_matchingServicesIterator];
+
+            [self _postStatusWithAction:kHIDRemoteDNStatusActionStart];
+
+            // Register for system wake notifications
+            [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(_computerDidWake:) name:NSWorkspaceDidWakeNotification object:nil];
+
+            return (YES);
+
+        }while(0);
+
+        // An error occured. Do necessary clean up.
+        if (matchDict!=NULL)
+        {
+            CFRelease(matchDict);
+            matchDict = NULL;
+        }
+
+        [self stopRemoteControl];
+    }
+
+    return (NO);
 }
 
 - (void)stopRemoteControl
 {
-	UInt32 serviceCount = 0;
-
-	_autoRecover = NO;
-	_isStopping = YES;
-
-	if (_autoRecoveryTimer!=nil)
-	{
-		[_autoRecoveryTimer invalidate];
-		[_autoRecoveryTimer release];
-		_autoRecoveryTimer = nil;
-	}
-
-	if (_serviceAttribMap!=nil)
-	{
-		NSDictionary *cloneDict = [[NSDictionary alloc] initWithDictionary:_serviceAttribMap];
-	
-		if (cloneDict!=nil)
-		{
-			NSEnumerator *mapKeyEnum = [cloneDict keyEnumerator];
-			NSNumber *serviceValue;
-			
-			while ((serviceValue = [mapKeyEnum nextObject]) != nil)
-			{
-				[self _destructService:(io_object_t)[serviceValue unsignedIntValue]];
-				serviceCount++;
-			};
-			
-			[cloneDict release];
-			cloneDict = nil;
-		}
-	
-		[_serviceAttribMap release];
-		_serviceAttribMap = nil;
-	}
-
-	if (_matchingServicesIterator!=0)
-	{
-		IOObjectRelease((io_object_t) _matchingServicesIterator);
-		_matchingServicesIterator = 0;
-	}
-	
-	if (_secureInputNotification!=0)
-	{
-		IOObjectRelease((io_object_t) _secureInputNotification);
-		_secureInputNotification = 0;
-	}
-
-	if (_notifyRLSource!=NULL)
-	{
-		CFRunLoopSourceInvalidate(_notifyRLSource);
-		_notifyRLSource = NULL;
-	}
-
-	if (_notifyPort!=NULL)
-	{
-		IONotificationPortDestroy(_notifyPort);
-		_notifyPort = NULL;
-	}
-
-	if (_masterPort!=0)
-	{
-		mach_port_deallocate(mach_task_self(), _masterPort);
-		_masterPort = 0;
-	}
-
-	if (_returnToPID!=nil)
-	{
-		[_returnToPID release];
-		_returnToPID = nil;
-	}
-
-	if (_mode!=kHIDRemoteModeNone)
-	{
-		// Post status
-		[self _postStatusWithAction:kHIDRemoteDNStatusActionStop];
-
-		if (_sendStatusNotifications)
-		{
-			// In case we were not ready to lend it earlier, tell other HIDRemote apps that the resources (if any were used) are now again available for use by other applications
-			if (((_mode==kHIDRemoteModeExclusive) || (_mode==kHIDRemoteModeExclusiveAuto)) && (_sendExclusiveResourceReuseNotification==YES) && (_exclusiveLockLending==NO) && (serviceCount>0))
-			{
-				_mode = kHIDRemoteModeNone;
-				
-				if (!_isRestarting)
-				{
-					[[NSDistributedNotificationCenter defaultCenter] postNotificationName:kHIDRemoteDNHIDRemoteRetry
-												       object:kHIDRemoteDNHIDRemoteRetryGlobalObject
-												     userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
-														[NSNumber numberWithUnsignedInt:(unsigned int)getpid()], kHIDRemoteDNStatusPIDKey,
-														[[NSBundle mainBundle] bundleIdentifier],		 (NSString *)kCFBundleIdentifierKey,
-													       nil]
-											   deliverImmediately:YES];
-				}
-			}
-		}
-
-		// Unregister from system wake notifications
-		[[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self name:NSWorkspaceDidWakeNotification object:nil];
-	}
-	
-	_mode = kHIDRemoteModeNone;
-	_isStopping = NO;
+    UInt32 serviceCount = 0;
+
+    _autoRecover = NO;
+    _isStopping = YES;
+
+    if (_autoRecoveryTimer!=nil)
+    {
+        [_autoRecoveryTimer invalidate];
+        HIDRemoteReleaseNil(_autoRecoveryTimer);
+    }
+
+    if (_serviceAttribMap!=nil)
+    {
+        NSDictionary *cloneDict = [[NSDictionary alloc] initWithDictionary:_serviceAttribMap];
+
+        if (cloneDict!=nil)
+        {
+            NSEnumerator *mapKeyEnum = [cloneDict keyEnumerator];
+            NSNumber *serviceValue;
+
+            while ((serviceValue = [mapKeyEnum nextObject]) != nil)
+            {
+                [self _destructService:(io_object_t)[serviceValue unsignedIntValue]];
+                serviceCount++;
+            };
+
+            HIDRemoteReleaseNil(cloneDict);
+        }
+
+        HIDRemoteReleaseNil(_serviceAttribMap);
+    }
+
+    if (_matchingServicesIterator!=0)
+    {
+        IOObjectRelease((io_object_t) _matchingServicesIterator);
+        _matchingServicesIterator = 0;
+    }
+
+    if (_secureInputNotification!=0)
+    {
+        IOObjectRelease((io_object_t) _secureInputNotification);
+        _secureInputNotification = 0;
+    }
+
+    if (_notifyRLSource!=NULL)
+    {
+        CFRunLoopSourceInvalidate(_notifyRLSource);
+        _notifyRLSource = NULL;
+    }
+
+    if (_notifyPort!=NULL)
+    {
+        IONotificationPortDestroy(_notifyPort);
+        _notifyPort = NULL;
+    }
+
+    if (_masterPort!=0)
+    {
+        mach_port_deallocate(mach_task_self(), _masterPort);
+        _masterPort = 0;
+    }
+
+    if (_returnToPID!=nil)
+    {
+        HIDRemoteReleaseNil(_returnToPID);
+    }
+
+    if (_mode!=kHIDRemoteModeNone)
+    {
+        // Post status
+        [self _postStatusWithAction:kHIDRemoteDNStatusActionStop];
+
+        if (_sendStatusNotifications)
+        {
+            // In case we were not ready to lend it earlier, tell other HIDRemote apps that the resources (if any were used) are now again available for use by other applications
+            if (((_mode==kHIDRemoteModeExclusive) || (_mode==kHIDRemoteModeExclusiveAuto)) && (_sendExclusiveResourceReuseNotification==YES) && (_exclusiveLockLending==NO) && (serviceCount>0))
+            {
+                _mode = kHIDRemoteModeNone;
+
+                if (!_isRestarting)
+                {
+                    [[NSDistributedNotificationCenter defaultCenter] postNotificationName:kHIDRemoteDNHIDRemoteRetry
+                                                       object:kHIDRemoteDNHIDRemoteRetryGlobalObject
+                                                     userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
+                                                        [NSNumber numberWithUnsignedInt:(unsigned int)getpid()], kHIDRemoteDNStatusPIDKey,
+                                                        [[NSBundle mainBundle] bundleIdentifier],		 (NSString *)kCFBundleIdentifierKey,
+                                                           nil]
+                                               deliverImmediately:YES];
+                }
+            }
+        }
+
+        // Unregister from system wake notifications
+        [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self name:NSWorkspaceDidWakeNotification object:nil];
+    }
+
+    _mode = kHIDRemoteModeNone;
+    _isStopping = NO;
 }
 
 - (BOOL)isStarted
 {
-	return (_mode != kHIDRemoteModeNone);
+    return (_mode != kHIDRemoteModeNone);
 }
 
 - (HIDRemoteMode)startedInMode
 {
-	return (_mode);
+    return (_mode);
 }
 
 - (unsigned)activeRemoteControlCount
 {
-	return ([_serviceAttribMap count]);
+    return ((unsigned)[_serviceAttribMap count]);
 }
 
 - (SInt32)lastSeenRemoteControlID
 {
-	return (_lastSeenRemoteID);
+    return (_lastSeenRemoteID);
 }
 
 - (HIDRemoteModel)lastSeenModel
 {
-	return (_lastSeenModel);
+    return (_lastSeenModel);
 }
 
 - (void)setLastSeenModel:(HIDRemoteModel)aModel
 {
-	_lastSeenModel = aModel;
+    _lastSeenModel = aModel;
 }
 
 - (void)setSimulateHoldEvents:(BOOL)newSimulateHoldEvents
 {
-	_simulateHoldEvents = newSimulateHoldEvents;
+    _simulateHoldEvents = newSimulateHoldEvents;
 }
 
 - (BOOL)simulateHoldEvents
 {
-	return (_simulateHoldEvents);
+    return (_simulateHoldEvents);
 }
 
 - (NSArray *)unusedButtonCodes
 {
-	return (_unusedButtonCodes);
+    return (_unusedButtonCodes);
 }
 
 - (void)setUnusedButtonCodes:(NSArray *)newArrayWithUnusedButtonCodesAsNSNumbers
 {
-	[newArrayWithUnusedButtonCodesAsNSNumbers retain];
-	[_unusedButtonCodes release];
-	
-	_unusedButtonCodes = newArrayWithUnusedButtonCodesAsNSNumbers;
+    HIDRemoteRetain(newArrayWithUnusedButtonCodesAsNSNumbers);
+    HIDRemoteRelease(_unusedButtonCodes);
+
+    _unusedButtonCodes = newArrayWithUnusedButtonCodesAsNSNumbers;
 
-	[self _postStatusWithAction:kHIDRemoteDNStatusActionUpdate];
+    [self _postStatusWithAction:kHIDRemoteDNStatusActionUpdate];
 }
 
 - (void)setDelegate:(NSObject <HIDRemoteDelegate> *)newDelegate
 {
-	_delegate = newDelegate;
+    _delegate = newDelegate;
 }
 
 - (NSObject <HIDRemoteDelegate> *)delegate
 {
-	return (_delegate);
+    return (_delegate);
 }
 
 #pragma mark - PUBLIC: Expert APIs
 - (void)setEnableSecureEventInputWorkaround:(BOOL)newEnableSecureEventInputWorkaround
 {
-	_secureEventInputWorkAround = newEnableSecureEventInputWorkaround;
+    _secureEventInputWorkAround = newEnableSecureEventInputWorkaround;
 }
 
 - (BOOL)enableSecureEventInputWorkaround
 {
-	return (_secureEventInputWorkAround);
+    return (_secureEventInputWorkAround);
 }
 
 - (void)setExclusiveLockLendingEnabled:(BOOL)newExclusiveLockLendingEnabled
 {
-	if (newExclusiveLockLendingEnabled != _exclusiveLockLending)
-	{
-		_exclusiveLockLending = newExclusiveLockLendingEnabled;
-		
-		if (_exclusiveLockLending)
-		{
-			[[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleNotifications:) name:kHIDRemoteDNHIDRemoteStatus object:nil];
-		}
-		else
-		{
-			[[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kHIDRemoteDNHIDRemoteStatus object:nil];
-			
-			[_waitForReturnByPID release];
-			_waitForReturnByPID = nil;
-		}
-	}
+    if (newExclusiveLockLendingEnabled != _exclusiveLockLending)
+    {
+        _exclusiveLockLending = newExclusiveLockLendingEnabled;
+
+        if (_exclusiveLockLending)
+        {
+            [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleNotifications:) name:kHIDRemoteDNHIDRemoteStatus object:nil];
+        }
+        else
+        {
+            [[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kHIDRemoteDNHIDRemoteStatus object:nil];
+
+            HIDRemoteReleaseNil(_waitForReturnByPID);
+        }
+    }
 }
 
 - (BOOL)exclusiveLockLendingEnabled
 {
-	return (_exclusiveLockLending);
+    return (_exclusiveLockLending);
 }
 
 - (void)setSendExclusiveResourceReuseNotification:(BOOL)newSendExclusiveResourceReuseNotification
 {
-	_sendExclusiveResourceReuseNotification = newSendExclusiveResourceReuseNotification;
+    _sendExclusiveResourceReuseNotification = newSendExclusiveResourceReuseNotification;
 }
 
 - (BOOL)sendExclusiveResourceReuseNotification
 {
-	return (_sendExclusiveResourceReuseNotification);
+    return (_sendExclusiveResourceReuseNotification);
 }
 
 - (BOOL)isApplicationTerminating
 {
-	return (_applicationIsTerminating);
+    return (_applicationIsTerminating);
 }
 
 - (BOOL)isStopping
 {
-	return (_isStopping);
+    return (_isStopping);
 }
 
 #pragma mark - PRIVATE: Application becomes active / inactive handling for kHIDRemoteModeExclusiveAuto
 - (void)_appStatusChanged:(NSNotification *)notification
 {
-	#ifdef HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING
-	if ([self respondsToSelector:@selector(performSelector:onThread:withObject:waitUntilDone:)]) // OS X 10.5+ only
-	{
-		if ([NSThread currentThread] != _runOnThread)
-		{
-			if ([[notification name] isEqual:NSApplicationDidBecomeActiveNotification])
-			{
-				if (!_autoRecover)
-				{
-					return;
-				}
-			}
-			
-			if ([[notification name] isEqual:NSApplicationWillResignActiveNotification])
-			{
-				if (_mode != kHIDRemoteModeExclusiveAuto)
-				{
-					return;
-				}
-			}
-		
-			[self performSelector:@selector(_appStatusChanged:) onThread:_runOnThread withObject:notification waitUntilDone:[[notification name] isEqual:NSApplicationWillTerminateNotification]];
-			return;
-		}
-	}
-	#endif
-
-	if (notification!=nil)
-	{
-		if (_autoRecoveryTimer!=nil)
-		{
-			[_autoRecoveryTimer invalidate];
-			[_autoRecoveryTimer release];
-			_autoRecoveryTimer = nil;
-		}
-
-		if ([[notification name] isEqual:NSApplicationDidBecomeActiveNotification])
-		{
-			if (_autoRecover)
-			{
-				// Delay autorecover by 0.1 to avoid race conditions
-				if ((_autoRecoveryTimer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:0.1] interval:0.1 target:self selector:@selector(_delayedAutoRecovery:) userInfo:nil repeats:NO]) != nil)
-				{
-					// Using CFRunLoopAddTimer instead of [[NSRunLoop currentRunLoop] addTimer:.. for consistency with run loop modes.
-					// The kCFRunLoopCommonModes counterpart NSRunLoopCommonModes is only available in 10.5 and later, whereas this code
-					// is designed to be also compatible with 10.4. CFRunLoopTimerRef is "toll-free-bridged" with NSTimer since 10.0.
-					CFRunLoopAddTimer(CFRunLoopGetCurrent(), (CFRunLoopTimerRef)_autoRecoveryTimer, kCFRunLoopCommonModes);
-				}
-			}
-		}
-
-		if ([[notification name] isEqual:NSApplicationWillResignActiveNotification])
-		{
-			if (_mode == kHIDRemoteModeExclusiveAuto)
-			{
-				[self stopRemoteControl];
-				_autoRecover = YES;
-			}
-		}
-		
-		if ([[notification name] isEqual:NSApplicationWillTerminateNotification])
-		{
-			_applicationIsTerminating = YES;
-		
-			if ([self isStarted])
-			{
-				[self stopRemoteControl];
-			}
-		}
-	}
+    #if HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING
+    if ([self respondsToSelector:@selector(performSelector:onThread:withObject:waitUntilDone:)]) // OS X 10.5+ only
+    {
+        if ([NSThread currentThread] != _runOnThread)
+        {
+            if ([[notification name] isEqual:NSApplicationDidBecomeActiveNotification])
+            {
+                if (!_autoRecover)
+                {
+                    return;
+                }
+            }
+
+            if ([[notification name] isEqual:NSApplicationWillResignActiveNotification])
+            {
+                if (_mode != kHIDRemoteModeExclusiveAuto)
+                {
+                    return;
+                }
+            }
+
+            [self performSelector:@selector(_appStatusChanged:) onThread:_runOnThread withObject:notification waitUntilDone:[[notification name] isEqual:NSApplicationWillTerminateNotification]];
+            return;
+        }
+    }
+    #endif
+
+    if (notification!=nil)
+    {
+        if (_autoRecoveryTimer!=nil)
+        {
+            [_autoRecoveryTimer invalidate];
+            HIDRemoteReleaseNil(_autoRecoveryTimer);
+        }
+
+        if ([[notification name] isEqual:NSApplicationDidBecomeActiveNotification])
+        {
+            if (_autoRecover)
+            {
+                // Delay autorecover by 0.1 to avoid race conditions
+                if ((_autoRecoveryTimer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:0.1] interval:0.1 target:self selector:@selector(_delayedAutoRecovery:) userInfo:nil repeats:NO]) != nil)
+                {
+                    // Using CFRunLoopAddTimer instead of [[NSRunLoop currentRunLoop] addTimer:.. for consistency with run loop modes.
+                    // The kCFRunLoopCommonModes counterpart NSRunLoopCommonModes is only available in 10.5 and later, whereas this code
+                    // is designed to be also compatible with 10.4. CFRunLoopTimerRef is "toll-free-bridged" with NSTimer since 10.0.
+                    CFRunLoopAddTimer(CFRunLoopGetCurrent(), (CFRunLoopTimerRef)_autoRecoveryTimer, kCFRunLoopCommonModes);
+                }
+            }
+        }
+
+        if ([[notification name] isEqual:NSApplicationWillResignActiveNotification])
+        {
+            if (_mode == kHIDRemoteModeExclusiveAuto)
+            {
+                [self stopRemoteControl];
+                _autoRecover = YES;
+            }
+        }
+
+        if ([[notification name] isEqual:NSApplicationWillTerminateNotification])
+        {
+            _applicationIsTerminating = YES;
+
+            if ([self isStarted])
+            {
+                [self stopRemoteControl];
+            }
+        }
+    }
 }
 
 - (void)_delayedAutoRecovery:(NSTimer *)aTimer
 {
-	[_autoRecoveryTimer invalidate];
-	[_autoRecoveryTimer release];
-	_autoRecoveryTimer = nil;
-
-	if (_autoRecover)
-	{
-		[self startRemoteControl:kHIDRemoteModeExclusiveAuto];
-		_autoRecover = NO;
-	}
+    [_autoRecoveryTimer invalidate];
+    HIDRemoteReleaseNil(_autoRecoveryTimer);
+
+    if (_autoRecover)
+    {
+        [self startRemoteControl:kHIDRemoteModeExclusiveAuto];
+        _autoRecover = NO;
+    }
 }
 
 
 #pragma mark - PRIVATE: Distributed notifiations handling
 - (void)_postStatusWithAction:(NSString *)action
 {
-	if (_sendStatusNotifications)
-	{
-		[[NSDistributedNotificationCenter defaultCenter] postNotificationName:kHIDRemoteDNHIDRemoteStatus
-									       object:((_pidString!=nil) ? _pidString : [NSString stringWithFormat:@"%d",getpid()])
-									     userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
-												[NSNumber numberWithInt:1],							kHIDRemoteDNStatusHIDRemoteVersionKey,
-												[NSNumber numberWithUnsignedInt:(unsigned int)getpid()],			kHIDRemoteDNStatusPIDKey,
-												[NSNumber numberWithInt:(int)_mode],						kHIDRemoteDNStatusModeKey,
-												[NSNumber numberWithUnsignedInt:(unsigned int)[self activeRemoteControlCount]], kHIDRemoteDNStatusRemoteControlCountKey,
-												((_unusedButtonCodes!=nil) ? _unusedButtonCodes : [NSArray array]),		kHIDRemoteDNStatusUnusedButtonCodesKey,
-												action,										kHIDRemoteDNStatusActionKey,
-												[[NSBundle mainBundle] bundleIdentifier],					(NSString *)kCFBundleIdentifierKey,
-												_returnToPID,									kHIDRemoteDNStatusReturnToPIDKey,
-										      nil]
-								   deliverImmediately:YES
-		];
-	}
+    if (_sendStatusNotifications)
+    {
+        [[NSDistributedNotificationCenter defaultCenter] postNotificationName:kHIDRemoteDNHIDRemoteStatus
+                                           object:((_pidString!=nil) ? _pidString : [NSString stringWithFormat:@"%d",getpid()])
+                                         userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
+                                                [NSNumber numberWithInt:1],							kHIDRemoteDNStatusHIDRemoteVersionKey,
+                                                [NSNumber numberWithUnsignedInt:(unsigned int)getpid()],			kHIDRemoteDNStatusPIDKey,
+                                                [NSNumber numberWithInt:(int)_mode],						kHIDRemoteDNStatusModeKey,
+                                                [NSNumber numberWithUnsignedInt:(unsigned int)[self activeRemoteControlCount]], kHIDRemoteDNStatusRemoteControlCountKey,
+                                                ((_unusedButtonCodes!=nil) ? _unusedButtonCodes : [NSArray array]),		kHIDRemoteDNStatusUnusedButtonCodesKey,
+                                                action,										kHIDRemoteDNStatusActionKey,
+                                                [[NSBundle mainBundle] bundleIdentifier],					(NSString *)kCFBundleIdentifierKey,
+                                                _returnToPID,									kHIDRemoteDNStatusReturnToPIDKey,
+                                              nil]
+                                   deliverImmediately:YES
+        ];
+    }
 }
 
 - (void)_handleNotifications:(NSNotification *)notification
 {
-	NSString *notificationName;
-
-	#ifdef HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING
-	if ([self respondsToSelector:@selector(performSelector:onThread:withObject:waitUntilDone:)]) // OS X 10.5+ only
-	{
-		if ([NSThread currentThread] != _runOnThread)
-		{
-			[self performSelector:@selector(_handleNotifications:) onThread:_runOnThread withObject:notification waitUntilDone:NO];
-			return;
-		}
-	}
-	#endif
-
-	if ((notification!=nil) && ((notificationName = [notification name]) != nil))
-	{
-		if ([notificationName isEqual:kHIDRemoteDNHIDRemotePing])
-		{
-			[self _postStatusWithAction:kHIDRemoteDNStatusActionUpdate];
-		}
-
-		if ([notificationName isEqual:kHIDRemoteDNHIDRemoteRetry])
-		{
-			if ([self isStarted])
-			{
-				BOOL retry = YES;
-				
-				// Ignore our own global retry broadcasts
-				if ([[notification object] isEqual:kHIDRemoteDNHIDRemoteRetryGlobalObject])
-				{
-					NSNumber *fromPID;
-
-					if ((fromPID = [[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey]) != nil)
-					{
-						if (getpid() == (int)[fromPID unsignedIntValue])
-						{
-							retry = NO;
-						}
-					}
-				}
-				
-				if (retry)
-				{
-					if (([self delegate] != nil) &&
-					    ([[self delegate] respondsToSelector:@selector(hidRemote:shouldRetryExclusiveLockWithInfo:)]))
-					{
-						retry = [[self delegate] hidRemote:self shouldRetryExclusiveLockWithInfo:[notification userInfo]];
-					}
-				}
-				
-				if (retry)
-				{
-					HIDRemoteMode restartInMode = _mode;
-					
-					if (restartInMode != kHIDRemoteModeNone)
-					{
-						_isRestarting = YES;
-						[self stopRemoteControl];
-						
-						[_returnToPID release];
-						_returnToPID = nil;
-	
-						[self startRemoteControl:restartInMode];
-						_isRestarting = NO;
-						
-						if (restartInMode != kHIDRemoteModeShared)
-						{
-							_returnToPID = [[[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey] retain];
-						}
-					}
-				}
-				else
-				{
-					NSNumber *cacheReturnPID = _returnToPID;
-
-					_returnToPID = [[[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey] retain];
-					[self _postStatusWithAction:kHIDRemoteDNStatusActionNoNeed];
-					[_returnToPID release];
-					
-					_returnToPID = cacheReturnPID;
-				}
-			}
-		}
-		
-		if (_exclusiveLockLending)
-		{
-			if ([notificationName isEqual:kHIDRemoteDNHIDRemoteStatus])
-			{
-				NSString *action;
-				
-				if ((action = [[notification userInfo] objectForKey:kHIDRemoteDNStatusActionKey]) != nil)
-				{
-					if ((_mode == kHIDRemoteModeNone) && (_waitForReturnByPID!=nil))
-					{
-						NSNumber *pidNumber, *returnToPIDNumber;
-
-						if ((pidNumber		= [[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey]) != nil)
-						{
-							returnToPIDNumber = [[notification userInfo] objectForKey:kHIDRemoteDNStatusReturnToPIDKey];
-						
-							if ([action isEqual:kHIDRemoteDNStatusActionStart])
-							{
-								if ([pidNumber isEqual:_waitForReturnByPID])
-								{
-									NSNumber *startMode;
-									
-									 if ((startMode = [[notification userInfo] objectForKey:kHIDRemoteDNStatusModeKey]) != nil)
-									 {
-										if ([startMode intValue] == kHIDRemoteModeShared)
-										{
-											returnToPIDNumber = [NSNumber numberWithInt:getpid()];
-											action = kHIDRemoteDNStatusActionNoNeed;
-										}
-									 }
-								}
-							}
-
-							if (returnToPIDNumber != nil)
-							{
-								if ([action isEqual:kHIDRemoteDNStatusActionStop] || [action isEqual:kHIDRemoteDNStatusActionNoNeed])
-								{
-									if ([pidNumber isEqual:_waitForReturnByPID] && ([returnToPIDNumber intValue] == getpid()))
-									{
-										[_waitForReturnByPID release];
-										_waitForReturnByPID = nil;
-									
-										if (([self delegate] != nil) &&
-										    ([[self delegate] respondsToSelector:@selector(hidRemote:exclusiveLockReleasedByApplicationWithInfo:)]))
-										{
-											[[self delegate] hidRemote:self exclusiveLockReleasedByApplicationWithInfo:[notification userInfo]];
-										}
-										else
-										{
-											[self startRemoteControl:kHIDRemoteModeExclusive];
-										}
-									}
-								}
-							}
-						}
-					}
-
-					if (_mode==kHIDRemoteModeExclusive)
-					{
-						if ([action isEqual:kHIDRemoteDNStatusActionStart])
-						{
-							NSNumber *originPID = [[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey];
-							BOOL lendLock = YES;
-						
-							if ([originPID intValue] != getpid())
-							{
-								if (([self delegate] != nil) &&
-								    ([[self delegate] respondsToSelector:@selector(hidRemote:lendExclusiveLockToApplicationWithInfo:)]))
-								{
-									lendLock = [[self delegate] hidRemote:self lendExclusiveLockToApplicationWithInfo:[notification userInfo]];
-								}
-								
-								if (lendLock)
-								{
-									[_waitForReturnByPID release];
-									_waitForReturnByPID = [originPID retain];
-									
-									if (_waitForReturnByPID != nil)
-									{
-										[self stopRemoteControl];
-										
-										[[NSDistributedNotificationCenter defaultCenter] postNotificationName:kHIDRemoteDNHIDRemoteRetry
-																	       object:[NSString stringWithFormat:@"%d", [_waitForReturnByPID intValue]]
-																	     userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
-																				[NSNumber numberWithUnsignedInt:(unsigned int)getpid()], kHIDRemoteDNStatusPIDKey,
-																				[[NSBundle mainBundle] bundleIdentifier],		 (NSString *)kCFBundleIdentifierKey,
-																		      nil]
-																   deliverImmediately:YES];
-									}
-								}
-							}
-						}
-					}
-				}
-			}
-		}
-	}
+    NSString *notificationName;
+
+    #if HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING
+    if ([self respondsToSelector:@selector(performSelector:onThread:withObject:waitUntilDone:)]) // OS X 10.5+ only
+    {
+        if ([NSThread currentThread] != _runOnThread)
+        {
+            [self performSelector:@selector(_handleNotifications:) onThread:_runOnThread withObject:notification waitUntilDone:NO];
+            return;
+        }
+    }
+    #endif
+
+    if ((notification!=nil) && ((notificationName = [notification name]) != nil))
+    {
+        if ([notificationName isEqual:kHIDRemoteDNHIDRemotePing])
+        {
+            [self _postStatusWithAction:kHIDRemoteDNStatusActionUpdate];
+        }
+
+        if ([notificationName isEqual:kHIDRemoteDNHIDRemoteRetry])
+        {
+            if ([self isStarted])
+            {
+                BOOL retry = YES;
+
+                // Ignore our own global retry broadcasts
+                if ([[notification object] isEqual:kHIDRemoteDNHIDRemoteRetryGlobalObject])
+                {
+                    NSNumber *fromPID;
+
+                    if ((fromPID = [[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey]) != nil)
+                    {
+                        if (getpid() == (int)[fromPID unsignedIntValue])
+                        {
+                            retry = NO;
+                        }
+                    }
+                }
+
+                if (retry)
+                {
+                    if (([self delegate] != nil) &&
+                        ([[self delegate] respondsToSelector:@selector(hidRemote:shouldRetryExclusiveLockWithInfo:)]))
+                    {
+                        retry = [[self delegate] hidRemote:self shouldRetryExclusiveLockWithInfo:[notification userInfo]];
+                    }
+                }
+
+                if (retry)
+                {
+                    HIDRemoteMode restartInMode = _mode;
+
+                    if (restartInMode != kHIDRemoteModeNone)
+                    {
+                        _isRestarting = YES;
+                        [self stopRemoteControl];
+
+                        HIDRemoteReleaseNil(_returnToPID);
+
+                        [self startRemoteControl:restartInMode];
+                        _isRestarting = NO;
+
+                        if (restartInMode != kHIDRemoteModeShared)
+                        {
+                            _returnToPID = HIDRemoteRetained([[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey]);
+                        }
+                    }
+                }
+                else
+                {
+                    NSNumber *cacheReturnPID = _returnToPID;
+
+                    _returnToPID = HIDRemoteRetained([[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey]);
+                    [self _postStatusWithAction:kHIDRemoteDNStatusActionNoNeed];
+                    HIDRemoteRelease(_returnToPID);
+
+                    _returnToPID = cacheReturnPID;
+                }
+            }
+        }
+
+        if (_exclusiveLockLending)
+        {
+            if ([notificationName isEqual:kHIDRemoteDNHIDRemoteStatus])
+            {
+                NSString *action;
+
+                if ((action = [[notification userInfo] objectForKey:kHIDRemoteDNStatusActionKey]) != nil)
+                {
+                    if ((_mode == kHIDRemoteModeNone) && (_waitForReturnByPID!=nil))
+                    {
+                        NSNumber *pidNumber, *returnToPIDNumber;
+
+                        if ((pidNumber		= [[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey]) != nil)
+                        {
+                            returnToPIDNumber = [[notification userInfo] objectForKey:kHIDRemoteDNStatusReturnToPIDKey];
+
+                            if ([action isEqual:kHIDRemoteDNStatusActionStart])
+                            {
+                                if ([pidNumber isEqual:_waitForReturnByPID])
+                                {
+                                    NSNumber *startMode;
+
+                                     if ((startMode = [[notification userInfo] objectForKey:kHIDRemoteDNStatusModeKey]) != nil)
+                                     {
+                                        if ([startMode intValue] == kHIDRemoteModeShared)
+                                        {
+                                            returnToPIDNumber = [NSNumber numberWithInt:getpid()];
+                                            action = kHIDRemoteDNStatusActionNoNeed;
+                                        }
+                                     }
+                                }
+                            }
+
+                            if (returnToPIDNumber != nil)
+                            {
+                                if ([action isEqual:kHIDRemoteDNStatusActionStop] || [action isEqual:kHIDRemoteDNStatusActionNoNeed])
+                                {
+                                    if ([pidNumber isEqual:_waitForReturnByPID] && ([returnToPIDNumber intValue] == getpid()))
+                                    {
+                                        HIDRemoteReleaseNil(_waitForReturnByPID);
+
+                                        if (([self delegate] != nil) &&
+                                            ([[self delegate] respondsToSelector:@selector(hidRemote:exclusiveLockReleasedByApplicationWithInfo:)]))
+                                        {
+                                            [[self delegate] hidRemote:self exclusiveLockReleasedByApplicationWithInfo:[notification userInfo]];
+                                        }
+                                        else
+                                        {
+                                            [self startRemoteControl:kHIDRemoteModeExclusive];
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+
+                    if (_mode==kHIDRemoteModeExclusive)
+                    {
+                        if ([action isEqual:kHIDRemoteDNStatusActionStart])
+                        {
+                            NSNumber *originPID = [[notification userInfo] objectForKey:kHIDRemoteDNStatusPIDKey];
+                            BOOL lendLock = YES;
+
+                            if ([originPID intValue] != getpid())
+                            {
+                                if (([self delegate] != nil) &&
+                                    ([[self delegate] respondsToSelector:@selector(hidRemote:lendExclusiveLockToApplicationWithInfo:)]))
+                                {
+                                    lendLock = [[self delegate] hidRemote:self lendExclusiveLockToApplicationWithInfo:[notification userInfo]];
+                                }
+
+                                if (lendLock)
+                                {
+                                    HIDRemoteRelease(_waitForReturnByPID);
+                                    _waitForReturnByPID = HIDRemoteRetained(originPID);
+
+                                    if (_waitForReturnByPID != nil)
+                                    {
+                                        [self stopRemoteControl];
+
+                                        [[NSDistributedNotificationCenter defaultCenter] postNotificationName:kHIDRemoteDNHIDRemoteRetry
+                                                                           object:[NSString stringWithFormat:@"%d", [_waitForReturnByPID intValue]]
+                                                                         userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
+                                                                                [NSNumber numberWithUnsignedInt:(unsigned int)getpid()], kHIDRemoteDNStatusPIDKey,
+                                                                                [[NSBundle mainBundle] bundleIdentifier],		 (NSString *)kCFBundleIdentifierKey,
+                                                                              nil]
+                                                                   deliverImmediately:YES];
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
 }
 
 - (void)_setSendStatusNotifications:(BOOL)doSend
 {
-	_sendStatusNotifications = doSend;
+    _sendStatusNotifications = doSend;
 }
 
 - (BOOL)_sendStatusNotifications
 {
-	return (_sendStatusNotifications);
+    return (_sendStatusNotifications);
 }
 
 #pragma mark - PRIVATE: Service setup and destruction
 - (BOOL)_prematchService:(io_object_t)service
 {
-	BOOL serviceMatches = NO;
-	NSString *ioClass;
-	NSNumber *candelairHIDRemoteCompatibilityMask;
-	
-	if (service != 0)
-	{
-		// IOClass matching
-		if ((ioClass = (NSString *)IORegistryEntryCreateCFProperty((io_registry_entry_t)service,
-									   CFSTR(kIOClassKey),
-									   kCFAllocatorDefault,
-									   0)) != nil)
-		{
-			// Match on Apple's AppleIRController and old versions of the Remote Buddy IR Controller
-			if ([ioClass isEqual:@"AppleIRController"] || [ioClass isEqual:@"RBIOKitAIREmu"])
-			{
-				CFTypeRef candelairHIDRemoteCompatibilityDevice;
-
-				serviceMatches = YES;
-				
-				if ((candelairHIDRemoteCompatibilityDevice = IORegistryEntryCreateCFProperty((io_registry_entry_t)service, CFSTR("CandelairHIDRemoteCompatibilityDevice"), kCFAllocatorDefault, 0)) != NULL)
-				{
-					if (CFEqual(kCFBooleanTrue, candelairHIDRemoteCompatibilityDevice))
-					{
-						serviceMatches = NO;
-					}
-					
-					CFRelease (candelairHIDRemoteCompatibilityDevice);
-				}
-			}
-
-			// Match on the virtual IOSPIRIT IR Controller
-			if ([ioClass isEqual:@"IOSPIRITIRController"])
-			{
-				serviceMatches = YES;
-			}
-			
-			CFRelease((CFTypeRef)ioClass);
-		}
-
-		// Match on services that claim compatibility with the HID Remote class (Candelair or third-party) by having a property of CandelairHIDRemoteCompatibilityMask = 1 <Type: Number>
-		if ((candelairHIDRemoteCompatibilityMask = (NSNumber *)IORegistryEntryCreateCFProperty((io_registry_entry_t)service, CFSTR("CandelairHIDRemoteCompatibilityMask"), kCFAllocatorDefault, 0)) != nil)
-		{
-			if ([candelairHIDRemoteCompatibilityMask isKindOfClass:[NSNumber class]])
-			{
-				if ([candelairHIDRemoteCompatibilityMask unsignedIntValue] & kHIDRemoteCompatibilityFlagsStandardHIDRemoteDevice)
-				{
-					serviceMatches = YES;
-				}
-				else
-				{
-					serviceMatches = NO;
-				}
-			}
-			
-			CFRelease((CFTypeRef)candelairHIDRemoteCompatibilityMask);
-		}
-	}
-
-	if (([self delegate]!=nil) &&
-	    ([[self delegate] respondsToSelector:@selector(hidRemote:inspectNewHardwareWithService:prematchResult:)]))
-	{
-		serviceMatches = [((NSObject <HIDRemoteDelegate> *)[self delegate]) hidRemote:self inspectNewHardwareWithService:service prematchResult:serviceMatches];
-	}
-	
-	return (serviceMatches);
+    BOOL serviceMatches = NO;
+    NSString *ioClass;
+    NSNumber *candelairHIDRemoteCompatibilityMask;
+
+    if (service != 0)
+    {
+        // IOClass matching
+        if ((ioClass = (__HIDRemoteBridge NSString *)IORegistryEntryCreateCFProperty((io_registry_entry_t)service,
+                                       CFSTR(kIOClassKey),
+                                       kCFAllocatorDefault,
+                                       0)) != nil)
+        {
+            // Match on Apple's AppleIRController and old versions of the Remote Buddy IR Controller
+            if ([ioClass isEqual:@"AppleIRController"] || [ioClass isEqual:@"RBIOKitAIREmu"])
+            {
+                CFTypeRef candelairHIDRemoteCompatibilityDevice;
+
+                serviceMatches = YES;
+
+                if ((candelairHIDRemoteCompatibilityDevice = IORegistryEntryCreateCFProperty((io_registry_entry_t)service, CFSTR("CandelairHIDRemoteCompatibilityDevice"), kCFAllocatorDefault, 0)) != NULL)
+                {
+                    if (CFEqual(kCFBooleanTrue, candelairHIDRemoteCompatibilityDevice))
+                    {
+                        serviceMatches = NO;
+                    }
+
+                    CFRelease (candelairHIDRemoteCompatibilityDevice);
+                }
+            }
+
+            // Match on the virtual IOSPIRIT IR Controller
+            if ([ioClass isEqual:@"IOSPIRITIRController"])
+            {
+                serviceMatches = YES;
+            }
+
+            CFRelease((CFTypeRef)ioClass);
+        }
+
+        // Match on services that claim compatibility with the HID Remote class (Candelair or third-party) by having a property of CandelairHIDRemoteCompatibilityMask = 1 <Type: Number>
+        if ((candelairHIDRemoteCompatibilityMask = (__HIDRemoteBridge NSNumber *)IORegistryEntryCreateCFProperty((io_registry_entry_t)service, CFSTR("CandelairHIDRemoteCompatibilityMask"), kCFAllocatorDefault, 0)) != nil)
+        {
+            if ([candelairHIDRemoteCompatibilityMask isKindOfClass:[NSNumber class]])
+            {
+                if ([candelairHIDRemoteCompatibilityMask unsignedIntValue] & kHIDRemoteCompatibilityFlagsStandardHIDRemoteDevice)
+                {
+                    serviceMatches = YES;
+                }
+                else
+                {
+                    serviceMatches = NO;
+                }
+            }
+
+            CFRelease((CFTypeRef)candelairHIDRemoteCompatibilityMask);
+        }
+    }
+
+    if (([self delegate]!=nil) &&
+        ([[self delegate] respondsToSelector:@selector(hidRemote:inspectNewHardwareWithService:prematchResult:)]))
+    {
+        serviceMatches = [((NSObject <HIDRemoteDelegate> *)[self delegate]) hidRemote:self inspectNewHardwareWithService:service prematchResult:serviceMatches];
+    }
+
+    return (serviceMatches);
 }
 
 - (HIDRemoteButtonCode)buttonCodeForUsage:(unsigned int)usage usagePage:(unsigned int)usagePage
 {
-	HIDRemoteButtonCode buttonCode = kHIDRemoteButtonCodeNone;
-
-	switch (usagePage)
-	{
-		case kHIDPage_Consumer:
-			switch (usage)
-			{
-				case kHIDUsage_Csmr_MenuPick:
-					// Aluminum Remote: Center
-					buttonCode = (kHIDRemoteButtonCodeCenter|kHIDRemoteButtonCodeAluminumMask);
-				break;
-				
-				case kHIDUsage_Csmr_ModeStep:
-					// Aluminium Remote: Center Hold
-					buttonCode = (kHIDRemoteButtonCodeCenterHold|kHIDRemoteButtonCodeAluminumMask);
-				break;
-
-				case kHIDUsage_Csmr_PlayOrPause:
-					// Aluminum Remote: Play/Pause
-					buttonCode = (kHIDRemoteButtonCodePlay|kHIDRemoteButtonCodeAluminumMask);
-				break;
-			
-				case kHIDUsage_Csmr_Rewind:
-					buttonCode = kHIDRemoteButtonCodeLeftHold;
-				break;
-				
-				case kHIDUsage_Csmr_FastForward:
-					buttonCode = kHIDRemoteButtonCodeRightHold;
-				break;
-
-				case kHIDUsage_Csmr_Menu:
-					buttonCode = kHIDRemoteButtonCodeMenuHold;
-				break;
-			}
-		break;
-		
-		case kHIDPage_GenericDesktop:
-			switch (usage)
-			{
-				case kHIDUsage_GD_SystemAppMenu:
-					buttonCode = kHIDRemoteButtonCodeMenu;
-				break;
-
-				case kHIDUsage_GD_SystemMenu:
-					buttonCode = kHIDRemoteButtonCodeCenter;
-				break;
-
-				case kHIDUsage_GD_SystemMenuRight:
-					buttonCode = kHIDRemoteButtonCodeRight;
-				break;
-
-				case kHIDUsage_GD_SystemMenuLeft:
-					buttonCode = kHIDRemoteButtonCodeLeft;
-				break;
-
-				case kHIDUsage_GD_SystemMenuUp:
-					buttonCode = kHIDRemoteButtonCodeUp;
-				break;
-
-				case kHIDUsage_GD_SystemMenuDown:
-					buttonCode = kHIDRemoteButtonCodeDown;
-				break;
-
-				case kHIDUsage_Csmr_VolumeIncrement:
-					buttonCode = kHIDRemoteButtonCodeUp;
-				break;
-
-				case kHIDUsage_Csmr_VolumeDecrement:
-					buttonCode = kHIDRemoteButtonCodeDown;
-				break;
-			}
-		break;
-		
-		case 0x06: /* Reserved */
-			switch (usage)
-			{
-				case 0x22:
-					buttonCode = kHIDRemoteButtonCodeIDChanged;
-				break;
-			}
-		break;
-		
-		case 0xFF01: /* Vendor specific */
-			switch (usage)
-			{
-				case 0x23:
-					buttonCode = kHIDRemoteButtonCodeCenterHold;
-				break;
-
-				#ifdef _HIDREMOTE_EXTENSIONS
-					#define _HIDREMOTE_EXTENSIONS_SECTION 2
-					#include "HIDRemoteAdditions.h"
-					#undef _HIDREMOTE_EXTENSIONS_SECTION
-				#endif /* _HIDREMOTE_EXTENSIONS */
-			}
-		break;
-	}
-	
-	return (buttonCode);
+    HIDRemoteButtonCode buttonCode = kHIDRemoteButtonCodeNone;
+
+    switch (usagePage)
+    {
+        case kHIDPage_Consumer:
+            switch (usage)
+            {
+                case kHIDUsage_Csmr_MenuPick:
+                    // Aluminum Remote: Center
+                    buttonCode = (kHIDRemoteButtonCodeCenter|kHIDRemoteButtonCodeAluminumMask);
+                break;
+
+                case kHIDUsage_Csmr_ModeStep:
+                    // Aluminium Remote: Center Hold
+                    buttonCode = (kHIDRemoteButtonCodeCenterHold|kHIDRemoteButtonCodeAluminumMask);
+                break;
+
+                case kHIDUsage_Csmr_PlayOrPause:
+                    // Aluminum Remote: Play/Pause
+                    buttonCode = (kHIDRemoteButtonCodePlay|kHIDRemoteButtonCodeAluminumMask);
+                break;
+
+                case kHIDUsage_Csmr_Rewind:
+                    buttonCode = kHIDRemoteButtonCodeLeftHold;
+                break;
+
+                case kHIDUsage_Csmr_FastForward:
+                    buttonCode = kHIDRemoteButtonCodeRightHold;
+                break;
+
+                case kHIDUsage_Csmr_Menu:
+                    buttonCode = kHIDRemoteButtonCodeMenuHold;
+                break;
+
+                case kHIDUsage_Csmr_VolumeIncrement:
+                    buttonCode = kHIDRemoteButtonCodeUp;
+                break;
+
+                case kHIDUsage_Csmr_VolumeDecrement:
+                    buttonCode = kHIDRemoteButtonCodeDown;
+                break;
+            }
+        break;
+
+        case kHIDPage_GenericDesktop:
+            switch (usage)
+            {
+                case kHIDUsage_GD_SystemAppMenu:
+                    buttonCode = kHIDRemoteButtonCodeMenu;
+                break;
+
+                case kHIDUsage_GD_SystemMenu:
+                    buttonCode = kHIDRemoteButtonCodeCenter;
+                break;
+
+                case kHIDUsage_GD_SystemMenuRight:
+                    buttonCode = kHIDRemoteButtonCodeRight;
+                break;
+
+                case kHIDUsage_GD_SystemMenuLeft:
+                    buttonCode = kHIDRemoteButtonCodeLeft;
+                break;
+
+                case kHIDUsage_GD_SystemMenuUp:
+                    buttonCode = kHIDRemoteButtonCodeUp;
+                break;
+
+                case kHIDUsage_GD_SystemMenuDown:
+                    buttonCode = kHIDRemoteButtonCodeDown;
+                break;
+            }
+        break;
+
+        case 0x06: /* Reserved */
+            switch (usage)
+            {
+                case 0x22:
+                    buttonCode = kHIDRemoteButtonCodeIDChanged;
+                break;
+            }
+        break;
+
+        case 0xFF01: /* Vendor specific */
+            switch (usage)
+            {
+                case 0x23:
+                    buttonCode = kHIDRemoteButtonCodeCenterHold;
+                break;
+
+                #ifdef _HIDREMOTE_EXTENSIONS
+                    #define _HIDREMOTE_EXTENSIONS_SECTION 2
+                    #include "HIDRemoteAdditions.h"
+                    #undef _HIDREMOTE_EXTENSIONS_SECTION
+                #endif /* _HIDREMOTE_EXTENSIONS */
+            }
+        break;
+    }
+
+    return (buttonCode);
 }
 
 - (BOOL)_setupService:(io_object_t)service
 {
-	kern_return_t		 kernResult;
-	IOReturn		 returnCode;
-	HRESULT			 hResult;
-	SInt32			 score;
-	BOOL			 opened = NO, queueStarted = NO;
-	IOHIDDeviceInterface122	 **hidDeviceInterface	= NULL;
-	IOCFPlugInInterface	 **cfPluginInterface	= NULL;
-	IOHIDQueueInterface	 **hidQueueInterface	= NULL;
-	io_object_t		 serviceNotification	= 0;
-	CFRunLoopSourceRef	 queueEventSource	= NULL;
-	NSMutableDictionary	 *hidAttribsDict	= nil;
-	CFArrayRef		 hidElements		= NULL;
-	NSError			 *error			= nil;
-	UInt32			 errorCode		= 0;
-
-	if (![self _prematchService:service])
-	{
-		return (NO);
-	}
-
-	do
-	{
-		// Create a plugin interface ..
-		kernResult = IOCreatePlugInInterfaceForService(	service,
-								kIOHIDDeviceUserClientTypeID,
-								kIOCFPlugInInterfaceID,
-								&cfPluginInterface,
-								&score);
-								
-		if (kernResult != kIOReturnSuccess)
-		{
-			error = [NSError errorWithDomain:NSMachErrorDomain code:kernResult userInfo:nil];
-			errorCode = 1;
-			break; 
-		}
-
-		
-		// .. use it to get the HID interface ..
-		hResult = (*cfPluginInterface)->QueryInterface(	cfPluginInterface, 
-								CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID122),
-								(LPVOID)&hidDeviceInterface);
-									
-		if ((hResult!=S_OK) || (hidDeviceInterface==NULL))
-		{
-			error = [NSError errorWithDomain:NSMachErrorDomain code:hResult userInfo:nil];
-			errorCode = 2;
-			break; 
-		}
-
-		
-		// .. then open it ..
-		switch (_mode)
-		{
-			case kHIDRemoteModeShared:
-				hResult = (*hidDeviceInterface)->open(hidDeviceInterface, kIOHIDOptionsTypeNone);
-			break;
-			
-			case kHIDRemoteModeExclusive:
-			case kHIDRemoteModeExclusiveAuto:
-				hResult = (*hidDeviceInterface)->open(hidDeviceInterface, kIOHIDOptionsTypeSeizeDevice);
-			break;
-			
-			default:
-				goto cleanUp; // Ugh! But there are no "double breaks" available in C AFAIK ..
-			break;
-		}
-		
-		if (hResult!=S_OK)
-		{
-			error = [NSError errorWithDomain:NSMachErrorDomain code:hResult userInfo:nil];
-			errorCode = 3;
-			break;
-		}
-		
-		opened = YES;
-
-		// .. query the HID elements ..
-		returnCode = (*hidDeviceInterface)->copyMatchingElements(hidDeviceInterface,
-									 NULL,
-									 &hidElements);
-		if ((returnCode != kIOReturnSuccess) || (hidElements==NULL))
-		{
-			error = [NSError errorWithDomain:NSMachErrorDomain code:returnCode userInfo:nil];
-			errorCode = 4;
-			
-			break;
-		}
-
-		// Setup an event queue for HID events!
-		hidQueueInterface = (*hidDeviceInterface)->allocQueue(hidDeviceInterface);
-		if (hidQueueInterface == NULL)
-		{
-			error = [NSError errorWithDomain:NSMachErrorDomain code:kIOReturnError userInfo:nil];
-			errorCode = 5;
-
-			break;
-		}
-
-		returnCode = (*hidQueueInterface)->create(hidQueueInterface, 0, 32);
-		if (returnCode != kIOReturnSuccess)
-		{
-			error = [NSError errorWithDomain:NSMachErrorDomain code:returnCode userInfo:nil];
-			errorCode = 6;
-
-			break;
-		}
-
-
-		// Setup of attributes stored for this HID device
-		hidAttribsDict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
-					[NSValue valueWithPointer:(const void *)cfPluginInterface],	kHIDRemoteCFPluginInterface,
-					[NSValue valueWithPointer:(const void *)hidDeviceInterface],	kHIDRemoteHIDDeviceInterface,
-					[NSValue valueWithPointer:(const void *)hidQueueInterface],	kHIDRemoteHIDQueueInterface,
-				 nil];
-
-		{
-			UInt32 i, hidElementCnt = CFArrayGetCount(hidElements);
-			NSMutableDictionary *cookieButtonCodeLUT = [[NSMutableDictionary alloc] init];
-			NSMutableDictionary *cookieCount	= [[NSMutableDictionary alloc] init];
-			
-			if ((cookieButtonCodeLUT==nil) || (cookieCount==nil))
-			{
-				[cookieButtonCodeLUT  release];
-				cookieButtonCodeLUT = nil;
-
-				[cookieCount	release];
-				cookieCount = nil;
-
-				error = [NSError errorWithDomain:NSMachErrorDomain code:kIOReturnError userInfo:nil];
-				errorCode = 7;
-
-				break;
-			}
-			
-			// Analyze the HID elements and find matching elements
-			for (i=0;i<hidElementCnt;i++)
-			{
-				CFDictionaryRef		hidDict;
-				NSNumber		*usage, *usagePage, *cookie;
-				HIDRemoteButtonCode	buttonCode = kHIDRemoteButtonCodeNone;
-				
-				hidDict = CFArrayGetValueAtIndex(hidElements, i);
-				
-				usage	  = (NSNumber *) CFDictionaryGetValue(hidDict, CFSTR(kIOHIDElementUsageKey));
-				usagePage = (NSNumber *) CFDictionaryGetValue(hidDict, CFSTR(kIOHIDElementUsagePageKey));
-				cookie    = (NSNumber *) CFDictionaryGetValue(hidDict, CFSTR(kIOHIDElementCookieKey));
-				
-				if ((usage!=nil) && (usagePage!=nil) && (cookie!=nil))
-				{
-					// Find the button codes for the ID combos
-					buttonCode = [self buttonCodeForUsage:[usage unsignedIntValue] usagePage:[usagePage unsignedIntValue]];
-
-					#ifdef _HIDREMOTE_EXTENSIONS
-						// Debug logging code
-						#define _HIDREMOTE_EXTENSIONS_SECTION 3
-						#include "HIDRemoteAdditions.h"
-						#undef _HIDREMOTE_EXTENSIONS_SECTION
-					#endif /* _HIDREMOTE_EXTENSIONS */
-					
-					// Did record match?
-					if (buttonCode != kHIDRemoteButtonCodeNone)
-					{
-						NSString *pairString	    = [[NSString alloc] initWithFormat:@"%u_%u", [usagePage unsignedIntValue], [usage unsignedIntValue]];
-						NSNumber *buttonCodeNumber  = [[NSNumber alloc] initWithUnsignedInt:(unsigned int)buttonCode];
-						
-						#ifdef _HIDREMOTE_EXTENSIONS
-							// Debug logging code
-							#define _HIDREMOTE_EXTENSIONS_SECTION 4
-							#include "HIDRemoteAdditions.h"
-							#undef _HIDREMOTE_EXTENSIONS_SECTION
-						#endif /* _HIDREMOTE_EXTENSIONS */
-						
-						[cookieCount		setObject:buttonCodeNumber forKey:pairString];
-						[cookieButtonCodeLUT	setObject:buttonCodeNumber forKey:cookie];
-						
-						(*hidQueueInterface)->addElement(hidQueueInterface,
-										 (IOHIDElementCookie) [cookie unsignedIntValue],
-										 0);
-
-						#ifdef _HIDREMOTE_EXTENSIONS
-							// Get current Apple Remote ID value
-							#define _HIDREMOTE_EXTENSIONS_SECTION 7
-							#include "HIDRemoteAdditions.h"
-							#undef _HIDREMOTE_EXTENSIONS_SECTION
-						#endif /* _HIDREMOTE_EXTENSIONS */
-						
-						[buttonCodeNumber release];
-						[pairString release];
-					}
-				}
-			}
-			
-			// Compare number of *unique* matches (thus the cookieCount dictionary) with required minimum
-			if ([cookieCount count] < 10)
-			{
-				[cookieButtonCodeLUT  release];
-				cookieButtonCodeLUT = nil;
-
-				[cookieCount	release];
-				cookieCount = nil;
-
-				error = [NSError errorWithDomain:NSMachErrorDomain code:kIOReturnError userInfo:nil];
-				errorCode = 8;
-
-				break;
-			}
-
-			[hidAttribsDict setObject:cookieButtonCodeLUT forKey:kHIDRemoteCookieButtonCodeLUT];
-
-			[cookieButtonCodeLUT  release];
-			cookieButtonCodeLUT = nil;
-
-			[cookieCount	release];
-			cookieCount = nil;
-		}
-		
-		// Finish setup of IOHIDQueueInterface with CFRunLoop
-		returnCode = (*hidQueueInterface)->createAsyncEventSource(hidQueueInterface, &queueEventSource);
-		if ((returnCode != kIOReturnSuccess) || (queueEventSource == NULL))
-		{
-			error = [NSError errorWithDomain:NSMachErrorDomain code:returnCode userInfo:nil];
-			errorCode = 9;
-			break; 
-		}
-		
-		returnCode = (*hidQueueInterface)->setEventCallout(hidQueueInterface, HIDEventCallback, (void *)((intptr_t)service), (void *)self);
-		if (returnCode != kIOReturnSuccess)
-		{
-			error = [NSError errorWithDomain:NSMachErrorDomain code:returnCode userInfo:nil];
-			errorCode = 10;
-			break;
-		}
-		
-		CFRunLoopAddSource(	CFRunLoopGetCurrent(),
-					queueEventSource,
-					kCFRunLoopCommonModes);
-		[hidAttribsDict setObject:[NSValue valueWithPointer:(const void *)queueEventSource] forKey:kHIDRemoteCFRunLoopSource];
-		
-		returnCode = (*hidQueueInterface)->start(hidQueueInterface);
-		if (returnCode != kIOReturnSuccess)
-		{
-			error = [NSError errorWithDomain:NSMachErrorDomain code:returnCode userInfo:nil];
-			errorCode = 11;
-			break;
-		}
-		
-		queueStarted = YES;
-
-		// Setup device notifications
-		returnCode = IOServiceAddInterestNotification(	_notifyPort,
-								service,
-								kIOGeneralInterest,
-								ServiceNotificationCallback,
-								self,
-								&serviceNotification);
-		if ((returnCode != kIOReturnSuccess) || (serviceNotification==0))
-		{
-			error = [NSError errorWithDomain:NSMachErrorDomain code:returnCode userInfo:nil];
-			errorCode = 12;
-			break;
-		}
-
-		[hidAttribsDict setObject:[NSNumber numberWithUnsignedInt:(unsigned int)serviceNotification] forKey:kHIDRemoteServiceNotification];
-		
-		// Retain service
-		if (IOObjectRetain(service) != kIOReturnSuccess)
-		{
-			error = [NSError errorWithDomain:NSMachErrorDomain code:kIOReturnError userInfo:nil];
-			errorCode = 13;
-			break;
-		}
-		
-		[hidAttribsDict setObject:[NSNumber numberWithUnsignedInt:(unsigned int)service] forKey:kHIDRemoteService];
-		
-		// Get some (somewhat optional) infos on the device
-		{
-			CFStringRef product, manufacturer, transport;
-		
-			if ((product = IORegistryEntryCreateCFProperty(	(io_registry_entry_t)service,
-									(CFStringRef) @"Product",
-									kCFAllocatorDefault,
-									0)) != NULL)
-			{
-				if (CFGetTypeID(product) == CFStringGetTypeID())
-				{
-					[hidAttribsDict setObject:(NSString *)product forKey:kHIDRemoteProduct];
-				}
-				
-				CFRelease(product);
-			}
-
-			if ((manufacturer = IORegistryEntryCreateCFProperty(	(io_registry_entry_t)service,
-										(CFStringRef) @"Manufacturer",
-										kCFAllocatorDefault,
-										0)) != NULL)
-			{
-				if (CFGetTypeID(manufacturer) == CFStringGetTypeID())
-				{
-					[hidAttribsDict setObject:(NSString *)manufacturer forKey:kHIDRemoteManufacturer];
-				}
-				
-				CFRelease(manufacturer);
-			}
-
-			if ((transport = IORegistryEntryCreateCFProperty(	(io_registry_entry_t)service,
-										(CFStringRef) @"Transport",
-										kCFAllocatorDefault,
-										0)) != NULL)
-			{
-				if (CFGetTypeID(transport) == CFStringGetTypeID())
-				{
-					[hidAttribsDict setObject:(NSString *)transport forKey:kHIDRemoteTransport];
-				}
-				
-				CFRelease(transport);
-			}
-		}
-		
-		// Determine Aluminum Remote support
-		{
-			CFNumberRef aluSupport;
-			HIDRemoteAluminumRemoteSupportLevel supportLevel = kHIDRemoteAluminumRemoteSupportLevelNone;
-			
-			if ((_mode == kHIDRemoteModeExclusive) || (_mode == kHIDRemoteModeExclusiveAuto))
-			{
-				// Determine if this driver offers on-demand support for the Aluminum Remote (only relevant under OS versions < 10.6.2)
-				if ((aluSupport = IORegistryEntryCreateCFProperty((io_registry_entry_t)service,
-										  (CFStringRef) @"AluminumRemoteSupportLevelOnDemand",
-										  kCFAllocatorDefault,
-										  0)) != nil)
-				{
-					// There is => request the driver to enable it for us
-					if (IORegistryEntrySetCFProperty((io_registry_entry_t)service,
-									 CFSTR("EnableAluminumRemoteSupportForMe"),
-									 [NSDictionary dictionaryWithObjectsAndKeys:
-										[NSNumber numberWithLongLong:(long long)getpid()],	@"pid",
-										[NSNumber numberWithLongLong:(long long)getuid()],	@"uid",
-									 nil]) == kIOReturnSuccess)
-					{
-						if (CFGetTypeID(aluSupport) == CFNumberGetTypeID())
-						{
-							supportLevel = (HIDRemoteAluminumRemoteSupportLevel) [(NSNumber *)aluSupport intValue];
-						}
-
-						[hidAttribsDict setObject:[NSNumber numberWithBool:YES] forKey:kHIDRemoteAluminumRemoteSupportOnDemand];
-					}
-					
-					CFRelease(aluSupport);
-				}
-			}
-			
-			if (supportLevel == kHIDRemoteAluminumRemoteSupportLevelNone)
-			{
-				if ((aluSupport = IORegistryEntryCreateCFProperty((io_registry_entry_t)service,
-										  (CFStringRef) @"AluminumRemoteSupportLevel",
-										  kCFAllocatorDefault,
-										  0)) != nil)
-				{
-					if (CFGetTypeID(aluSupport) == CFNumberGetTypeID())
-					{
-						supportLevel = (HIDRemoteAluminumRemoteSupportLevel) [(NSNumber *)aluSupport intValue];
-					}
-					
-					CFRelease(aluSupport);
-				}
-				else
-				{
-					CFStringRef ioKitClassName;
-				
-					if ((ioKitClassName = IORegistryEntryCreateCFProperty(	(io_registry_entry_t)service,
-												CFSTR(kIOClassKey),
-												kCFAllocatorDefault,
-												0)) != nil)
-					{
-						if ([(NSString *)ioKitClassName isEqual:@"AppleIRController"])
-						{
-							if ([HIDRemote OSXVersion] >= 0x1062)
-							{
-								// Support for the Aluminum Remote was added only with OS 10.6.2. Previous versions can not distinguish
-								// between the Center and the new, seperate Play/Pause button. They'll recognize both as presses of the
-								// "Center" button.
-								//
-								// You CAN, however, receive Aluminum Remote button presses even under OS 10.5 when using Remote Buddy's
-								// Virtual Remote. While Remote Buddy does support the Aluminum Remote across all OS releases it runs on,
-								// its Virtual Remote can only emulate Aluminum Remote button presses under OS 10.5 and up in order not to
-								// break compatibility with applications whose IR Remote code relies on driver internals. [13-Nov-09]
-								supportLevel = kHIDRemoteAluminumRemoteSupportLevelNative;
-							}
-						}
-						
-						CFRelease(ioKitClassName);
-					}
-				}
-			}
-
-			[hidAttribsDict setObject:(NSNumber *)[NSNumber numberWithInt:(int)supportLevel] forKey:kHIDRemoteAluminumRemoteSupportLevel];
-		}
-		
-		// Add it to the serviceAttribMap
-		[_serviceAttribMap setObject:hidAttribsDict forKey:[NSNumber numberWithUnsignedInt:(unsigned int)service]];
-		
-		// And we're done with setup ..
-		if (([self delegate]!=nil) &&
-		    ([[self delegate] respondsToSelector:@selector(hidRemote:foundNewHardwareWithAttributes:)]))
-		{
-			[((NSObject <HIDRemoteDelegate> *)[self delegate]) hidRemote:self foundNewHardwareWithAttributes:hidAttribsDict];
-		}
-		
-		[hidAttribsDict release];
-		hidAttribsDict = nil;
-		
-		return(YES);
-
-	}while(0);
-	
-	cleanUp:
-
-	if (([self delegate]!=nil) &&
-	    ([[self delegate] respondsToSelector:@selector(hidRemote:failedNewHardwareWithError:)]))
-	{
-		if (error!=nil)
-		{
-			error = [NSError errorWithDomain:[error domain] 
-						    code:[error code]
-						userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:errorCode] forKey:@"InternalErrorCode"]
-				];
-		}
-
-		[((NSObject <HIDRemoteDelegate> *)[self delegate]) hidRemote:self failedNewHardwareWithError:error];
-	}
-	
-	// An error occured or this device is not of interest .. cleanup ..
-	if (serviceNotification!=0)
-	{
-		IOObjectRelease(serviceNotification);
-		serviceNotification = 0;
-	}
-
-	if (queueEventSource!=NULL)
-	{
-		CFRunLoopSourceInvalidate(queueEventSource);
-		queueEventSource=NULL;
-	}
-	
-	if (hidQueueInterface!=NULL)
-	{
-		if (queueStarted)
-		{
-			(*hidQueueInterface)->stop(hidQueueInterface);
-		}
-		(*hidQueueInterface)->dispose(hidQueueInterface);
-		(*hidQueueInterface)->Release(hidQueueInterface);
-		hidQueueInterface = NULL;
-	}
-
-	if (hidAttribsDict!=nil)
-	{
-		[hidAttribsDict release];
-		hidAttribsDict = nil;
-	}
-	
-	if (hidElements!=NULL)
-	{
-		CFRelease(hidElements);
-		hidElements = NULL;
-	}
-	
-	if (hidDeviceInterface!=NULL)
-	{
-		if (opened)
-		{
-			(*hidDeviceInterface)->close(hidDeviceInterface);
-		}
-		(*hidDeviceInterface)->Release(hidDeviceInterface);
-		// opened = NO;
-		hidDeviceInterface = NULL;
-	}
-	
-	if (cfPluginInterface!=NULL)
-	{
-		IODestroyPlugInInterface(cfPluginInterface);
-		cfPluginInterface = NULL;
-	}
-	
-	return (NO);
+    kern_return_t		 kernResult;
+    IOReturn		 returnCode;
+    HRESULT			 hResult;
+    SInt32			 score;
+    BOOL			 opened = NO, queueStarted = NO;
+    IOHIDDeviceInterface122	 **hidDeviceInterface	= NULL;
+    IOCFPlugInInterface	 **cfPluginInterface	= NULL;
+    IOHIDQueueInterface	 **hidQueueInterface	= NULL;
+    io_object_t		 serviceNotification	= 0;
+    CFRunLoopSourceRef	 queueEventSource	= NULL;
+    NSMutableDictionary	 *hidAttribsDict	= nil;
+    CFArrayRef		 hidElements		= NULL;
+    NSError			 *error			= nil;
+    UInt32			 errorCode		= 0;
+
+    if (![self _prematchService:service])
+    {
+        return (NO);
+    }
+
+    do
+    {
+        // Create a plugin interface ..
+        kernResult = IOCreatePlugInInterfaceForService(	service,
+                                kIOHIDDeviceUserClientTypeID,
+                                kIOCFPlugInInterfaceID,
+                                &cfPluginInterface,
+                                &score);
+
+        if (kernResult != kIOReturnSuccess)
+        {
+            error = [NSError errorWithDomain:NSMachErrorDomain code:kernResult userInfo:nil];
+            errorCode = 1;
+            break;
+        }
+
+
+        // .. use it to get the HID interface ..
+        hResult = (*cfPluginInterface)->QueryInterface(	cfPluginInterface,
+                                CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID122),
+                                (LPVOID)&hidDeviceInterface);
+
+        if ((hResult!=S_OK) || (hidDeviceInterface==NULL))
+        {
+            error = [NSError errorWithDomain:NSMachErrorDomain code:hResult userInfo:nil];
+            errorCode = 2;
+            break;
+        }
+
+
+        // .. then open it ..
+        switch (_mode)
+        {
+            case kHIDRemoteModeShared:
+                hResult = (*hidDeviceInterface)->open(hidDeviceInterface, kIOHIDOptionsTypeNone);
+            break;
+
+            case kHIDRemoteModeExclusive:
+            case kHIDRemoteModeExclusiveAuto:
+                hResult = (*hidDeviceInterface)->open(hidDeviceInterface, kIOHIDOptionsTypeSeizeDevice);
+            break;
+
+            default:
+                goto cleanUp; // Ugh! But there are no "double breaks" available in C AFAIK ..
+            break;
+        }
+
+        if (hResult!=S_OK)
+        {
+            error = [NSError errorWithDomain:NSMachErrorDomain code:hResult userInfo:nil];
+            errorCode = 3;
+            break;
+        }
+
+        opened = YES;
+
+        // .. query the HID elements ..
+        returnCode = (*hidDeviceInterface)->copyMatchingElements(hidDeviceInterface,
+                                     NULL,
+                                     &hidElements);
+        if ((returnCode != kIOReturnSuccess) || (hidElements==NULL))
+        {
+            error = [NSError errorWithDomain:NSMachErrorDomain code:returnCode userInfo:nil];
+            errorCode = 4;
+
+            break;
+        }
+
+        // Setup an event queue for HID events!
+        hidQueueInterface = (*hidDeviceInterface)->allocQueue(hidDeviceInterface);
+        if (hidQueueInterface == NULL)
+        {
+            error = [NSError errorWithDomain:NSMachErrorDomain code:kIOReturnError userInfo:nil];
+            errorCode = 5;
+
+            break;
+        }
+
+        returnCode = (*hidQueueInterface)->create(hidQueueInterface, 0, 32);
+        if (returnCode != kIOReturnSuccess)
+        {
+            error = [NSError errorWithDomain:NSMachErrorDomain code:returnCode userInfo:nil];
+            errorCode = 6;
+
+            break;
+        }
+
+
+        // Setup of attributes stored for this HID device
+        hidAttribsDict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
+                    [NSValue valueWithPointer:(const void *)cfPluginInterface],	kHIDRemoteCFPluginInterface,
+                    [NSValue valueWithPointer:(const void *)hidDeviceInterface],	kHIDRemoteHIDDeviceInterface,
+                    [NSValue valueWithPointer:(const void *)hidQueueInterface],	kHIDRemoteHIDQueueInterface,
+                 nil];
+
+        {
+            UInt32 i, hidElementCnt = (UInt32)CFArrayGetCount(hidElements);
+            NSMutableDictionary *cookieButtonCodeLUT = [[NSMutableDictionary alloc] init];
+            NSMutableDictionary *cookieCount	= [[NSMutableDictionary alloc] init];
+
+            if ((cookieButtonCodeLUT==nil) || (cookieCount==nil))
+            {
+                HIDRemoteReleaseNil(cookieButtonCodeLUT);
+                HIDRemoteReleaseNil(cookieCount);
+
+                error = [NSError errorWithDomain:NSMachErrorDomain code:kIOReturnError userInfo:nil];
+                errorCode = 7;
+
+                break;
+            }
+
+            // Analyze the HID elements and find matching elements
+            for (i=0;i<hidElementCnt;i++)
+            {
+                CFDictionaryRef		hidDict;
+                NSNumber		*usage, *usagePage, *cookie;
+                HIDRemoteButtonCode	buttonCode = kHIDRemoteButtonCodeNone;
+
+                hidDict = CFArrayGetValueAtIndex(hidElements, i);
+
+                usage	  = (NSNumber *) CFDictionaryGetValue(hidDict, CFSTR(kIOHIDElementUsageKey));
+                usagePage = (NSNumber *) CFDictionaryGetValue(hidDict, CFSTR(kIOHIDElementUsagePageKey));
+                cookie    = (NSNumber *) CFDictionaryGetValue(hidDict, CFSTR(kIOHIDElementCookieKey));
+
+                if ((usage!=nil) && (usagePage!=nil) && (cookie!=nil))
+                {
+                    // Find the button codes for the ID combos
+                    buttonCode = [self buttonCodeForUsage:[usage unsignedIntValue] usagePage:[usagePage unsignedIntValue]];
+
+                    #ifdef _HIDREMOTE_EXTENSIONS
+                        // Debug logging code
+                        #define _HIDREMOTE_EXTENSIONS_SECTION 3
+                        #include "HIDRemoteAdditions.h"
+                        #undef _HIDREMOTE_EXTENSIONS_SECTION
+                    #endif /* _HIDREMOTE_EXTENSIONS */
+
+                    // Did record match?
+                    if (buttonCode != kHIDRemoteButtonCodeNone)
+                    {
+                        NSString *pairString	    = [[NSString alloc] initWithFormat:@"%u_%u", [usagePage unsignedIntValue], [usage unsignedIntValue]];
+                        NSNumber *buttonCodeNumber  = [[NSNumber alloc] initWithUnsignedInt:(unsigned int)buttonCode];
+
+                        #ifdef _HIDREMOTE_EXTENSIONS
+                            // Debug logging code
+                            #define _HIDREMOTE_EXTENSIONS_SECTION 4
+                            #include "HIDRemoteAdditions.h"
+                            #undef _HIDREMOTE_EXTENSIONS_SECTION
+                        #endif /* _HIDREMOTE_EXTENSIONS */
+
+                        [cookieCount		setObject:buttonCodeNumber forKey:pairString];
+                        [cookieButtonCodeLUT	setObject:buttonCodeNumber forKey:cookie];
+
+                        (*hidQueueInterface)->addElement(hidQueueInterface,
+                                         (IOHIDElementCookie) [cookie unsignedIntValue],
+                                         0);
+
+                        #ifdef _HIDREMOTE_EXTENSIONS
+                            // Get current Apple Remote ID value
+                            #define _HIDREMOTE_EXTENSIONS_SECTION 7
+                            #include "HIDRemoteAdditions.h"
+                            #undef _HIDREMOTE_EXTENSIONS_SECTION
+                        #endif /* _HIDREMOTE_EXTENSIONS */
+
+                        HIDRemoteRelease(buttonCodeNumber);
+                        HIDRemoteRelease(pairString);
+                    }
+                }
+            }
+
+            // Compare number of *unique* matches (thus the cookieCount dictionary) with required minimum
+            if ([cookieCount count] < 10)
+            {
+                HIDRemoteReleaseNil(cookieButtonCodeLUT);
+                HIDRemoteReleaseNil(cookieCount);
+
+                error = [NSError errorWithDomain:NSMachErrorDomain code:kIOReturnError userInfo:nil];
+                errorCode = 8;
+
+                break;
+            }
+
+            [hidAttribsDict setObject:cookieButtonCodeLUT forKey:kHIDRemoteCookieButtonCodeLUT];
+
+            HIDRemoteReleaseNil(cookieButtonCodeLUT);
+            HIDRemoteReleaseNil(cookieCount);
+        }
+
+        // Finish setup of IOHIDQueueInterface with CFRunLoop
+        returnCode = (*hidQueueInterface)->createAsyncEventSource(hidQueueInterface, &queueEventSource);
+        if ((returnCode != kIOReturnSuccess) || (queueEventSource == NULL))
+        {
+            error = [NSError errorWithDomain:NSMachErrorDomain code:returnCode userInfo:nil];
+            errorCode = 9;
+            break;
+        }
+
+        returnCode = (*hidQueueInterface)->setEventCallout(hidQueueInterface, HIDEventCallback, (void *)((intptr_t)service), (__HIDRemoteBridge void *)self);
+        if (returnCode != kIOReturnSuccess)
+        {
+            error = [NSError errorWithDomain:NSMachErrorDomain code:returnCode userInfo:nil];
+            errorCode = 10;
+            break;
+        }
+
+        CFRunLoopAddSource(	CFRunLoopGetCurrent(),
+                    queueEventSource,
+                    kCFRunLoopCommonModes);
+        [hidAttribsDict setObject:[NSValue valueWithPointer:(const void *)queueEventSource] forKey:kHIDRemoteCFRunLoopSource];
+
+        returnCode = (*hidQueueInterface)->start(hidQueueInterface);
+        if (returnCode != kIOReturnSuccess)
+        {
+            error = [NSError errorWithDomain:NSMachErrorDomain code:returnCode userInfo:nil];
+            errorCode = 11;
+            break;
+        }
+
+        queueStarted = YES;
+
+        // Setup device notifications
+        returnCode = IOServiceAddInterestNotification(	_notifyPort,
+                                service,
+                                kIOGeneralInterest,
+                                ServiceNotificationCallback,
+                                (__HIDRemoteBridge void *)(self),
+                                &serviceNotification);
+        if ((returnCode != kIOReturnSuccess) || (serviceNotification==0))
+        {
+            error = [NSError errorWithDomain:NSMachErrorDomain code:returnCode userInfo:nil];
+            errorCode = 12;
+            break;
+        }
+
+        [hidAttribsDict setObject:[NSNumber numberWithUnsignedInt:(unsigned int)serviceNotification] forKey:kHIDRemoteServiceNotification];
+
+        // Retain service
+        if (IOObjectRetain(service) != kIOReturnSuccess)
+        {
+            error = [NSError errorWithDomain:NSMachErrorDomain code:kIOReturnError userInfo:nil];
+            errorCode = 13;
+            break;
+        }
+
+        [hidAttribsDict setObject:[NSNumber numberWithUnsignedInt:(unsigned int)service] forKey:kHIDRemoteService];
+
+        // Get some (somewhat optional) infos on the device
+        {
+            CFStringRef product, manufacturer, transport;
+
+            if ((product = IORegistryEntryCreateCFProperty(	(io_registry_entry_t)service,
+                                    (CFStringRef) @"Product",
+                                    kCFAllocatorDefault,
+                                    0)) != NULL)
+            {
+                if (CFGetTypeID(product) == CFStringGetTypeID())
+                {
+                    [hidAttribsDict setObject:(__HIDRemoteBridge NSString *)product forKey:kHIDRemoteProduct];
+                }
+
+                CFRelease(product);
+            }
+
+            if ((manufacturer = IORegistryEntryCreateCFProperty(	(io_registry_entry_t)service,
+                                        (CFStringRef) @"Manufacturer",
+                                        kCFAllocatorDefault,
+                                        0)) != NULL)
+            {
+                if (CFGetTypeID(manufacturer) == CFStringGetTypeID())
+                {
+                    [hidAttribsDict setObject:(__HIDRemoteBridge NSString *)manufacturer forKey:kHIDRemoteManufacturer];
+                }
+
+                CFRelease(manufacturer);
+            }
+
+            if ((transport = IORegistryEntryCreateCFProperty(	(io_registry_entry_t)service,
+                                        (CFStringRef) @"Transport",
+                                        kCFAllocatorDefault,
+                                        0)) != NULL)
+            {
+                if (CFGetTypeID(transport) == CFStringGetTypeID())
+                {
+                    [hidAttribsDict setObject:(__HIDRemoteBridge NSString *)transport forKey:kHIDRemoteTransport];
+                }
+
+                CFRelease(transport);
+            }
+        }
+
+        // Determine Aluminum Remote support
+        {
+            CFNumberRef aluSupport;
+            HIDRemoteAluminumRemoteSupportLevel supportLevel = kHIDRemoteAluminumRemoteSupportLevelNone;
+
+            if ((_mode == kHIDRemoteModeExclusive) || (_mode == kHIDRemoteModeExclusiveAuto))
+            {
+                // Determine if this driver offers on-demand support for the Aluminum Remote (only relevant under OS versions < 10.6.2)
+                if ((aluSupport = IORegistryEntryCreateCFProperty((io_registry_entry_t)service,
+                                          (CFStringRef) @"AluminumRemoteSupportLevelOnDemand",
+                                          kCFAllocatorDefault,
+                                          0)) != nil)
+                {
+                    // There is => request the driver to enable it for us
+                    if (IORegistryEntrySetCFProperty((io_registry_entry_t)service,
+                                     CFSTR("EnableAluminumRemoteSupportForMe"),
+                                     (__HIDRemoteBridge CFTypeRef)([NSDictionary dictionaryWithObjectsAndKeys:
+                                        [NSNumber numberWithLongLong:(long long)getpid()],	@"pid",
+                                        [NSNumber numberWithLongLong:(long long)getuid()],	@"uid",
+                                     nil])) == kIOReturnSuccess)
+                    {
+                        if (CFGetTypeID(aluSupport) == CFNumberGetTypeID())
+                        {
+                            supportLevel = (HIDRemoteAluminumRemoteSupportLevel) [(__HIDRemoteBridge NSNumber *)aluSupport intValue];
+                        }
+
+                        [hidAttribsDict setObject:[NSNumber numberWithBool:YES] forKey:kHIDRemoteAluminumRemoteSupportOnDemand];
+                    }
+
+                    CFRelease(aluSupport);
+                }
+            }
+
+            if (supportLevel == kHIDRemoteAluminumRemoteSupportLevelNone)
+            {
+                if ((aluSupport = IORegistryEntryCreateCFProperty((io_registry_entry_t)service,
+                                          (CFStringRef) @"AluminumRemoteSupportLevel",
+                                          kCFAllocatorDefault,
+                                          0)) != nil)
+                {
+                    if (CFGetTypeID(aluSupport) == CFNumberGetTypeID())
+                    {
+                        supportLevel = (HIDRemoteAluminumRemoteSupportLevel) [(__HIDRemoteBridge NSNumber *)aluSupport intValue];
+                    }
+
+                    CFRelease(aluSupport);
+                }
+                else
+                {
+                    CFStringRef ioKitClassName;
+
+                    if ((ioKitClassName = IORegistryEntryCreateCFProperty(	(io_registry_entry_t)service,
+                                                CFSTR(kIOClassKey),
+                                                kCFAllocatorDefault,
+                                                0)) != nil)
+                    {
+                        if ([(__HIDRemoteBridge NSString *)ioKitClassName isEqual:@"AppleIRController"])
+                        {
+                            if ([HIDRemote OSXVersion] >= 0x1062)
+                            {
+                                // Support for the Aluminum Remote was added only with OS 10.6.2. Previous versions can not distinguish
+                                // between the Center and the new, seperate Play/Pause button. They'll recognize both as presses of the
+                                // "Center" button.
+                                //
+                                // You CAN, however, receive Aluminum Remote button presses even under OS 10.5 when using Remote Buddy's
+                                // Virtual Remote. While Remote Buddy does support the Aluminum Remote across all OS releases it runs on,
+                                // its Virtual Remote can only emulate Aluminum Remote button presses under OS 10.5 and up in order not to
+                                // break compatibility with applications whose IR Remote code relies on driver internals. [13-Nov-09]
+                                supportLevel = kHIDRemoteAluminumRemoteSupportLevelNative;
+                            }
+                        }
+
+                        CFRelease(ioKitClassName);
+                    }
+                }
+            }
+
+            [hidAttribsDict setObject:(NSNumber *)[NSNumber numberWithInt:(int)supportLevel] forKey:kHIDRemoteAluminumRemoteSupportLevel];
+        }
+
+        // Add it to the serviceAttribMap
+        [_serviceAttribMap setObject:hidAttribsDict forKey:[NSNumber numberWithUnsignedInt:(unsigned int)service]];
+
+        // And we're done with setup ..
+        if (([self delegate]!=nil) &&
+            ([[self delegate] respondsToSelector:@selector(hidRemote:foundNewHardwareWithAttributes:)]))
+        {
+            [((NSObject <HIDRemoteDelegate> *)[self delegate]) hidRemote:self foundNewHardwareWithAttributes:hidAttribsDict];
+        }
+
+        HIDRemoteReleaseNil(hidAttribsDict);
+
+        return(YES);
+
+    }while(0);
+
+    cleanUp:
+
+    if (([self delegate]!=nil) &&
+        ([[self delegate] respondsToSelector:@selector(hidRemote:failedNewHardwareWithError:)]))
+    {
+        if (error!=nil)
+        {
+            error = [NSError errorWithDomain:[error domain]
+                            code:[error code]
+                        userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:errorCode] forKey:@"InternalErrorCode"]
+                ];
+        }
+
+        [((NSObject <HIDRemoteDelegate> *)[self delegate]) hidRemote:self failedNewHardwareWithError:error];
+    }
+
+    // An error occured or this device is not of interest .. cleanup ..
+    if (serviceNotification!=0)
+    {
+        IOObjectRelease(serviceNotification);
+        serviceNotification = 0;
+    }
+
+    if (queueEventSource!=NULL)
+    {
+        CFRunLoopSourceInvalidate(queueEventSource);
+        queueEventSource=NULL;
+    }
+
+    if (hidQueueInterface!=NULL)
+    {
+        if (queueStarted)
+        {
+            (*hidQueueInterface)->stop(hidQueueInterface);
+        }
+        (*hidQueueInterface)->dispose(hidQueueInterface);
+        (*hidQueueInterface)->Release(hidQueueInterface);
+        hidQueueInterface = NULL;
+    }
+
+    if (hidAttribsDict!=nil)
+    {
+        HIDRemoteReleaseNil(hidAttribsDict);
+    }
+
+    if (hidElements!=NULL)
+    {
+        CFRelease(hidElements);
+        hidElements = NULL;
+    }
+
+    if (hidDeviceInterface!=NULL)
+    {
+        if (opened)
+        {
+            (*hidDeviceInterface)->close(hidDeviceInterface);
+        }
+        (*hidDeviceInterface)->Release(hidDeviceInterface);
+        // opened = NO;
+        hidDeviceInterface = NULL;
+    }
+
+    if (cfPluginInterface!=NULL)
+    {
+        IODestroyPlugInInterface(cfPluginInterface);
+        cfPluginInterface = NULL;
+    }
+
+    return (NO);
 }
 
 - (void)_destructService:(io_object_t)service
 {
-	NSNumber	    *serviceValue;
-	NSMutableDictionary *serviceDict = NULL;
-	
-	if ((serviceValue = [NSNumber numberWithUnsignedInt:(unsigned int)service]) == nil)
-	{
-		return;
-	}
-	
-	serviceDict  = [_serviceAttribMap objectForKey:serviceValue];
-	
-	if (serviceDict!=nil)
-	{
-		IOHIDDeviceInterface122	 **hidDeviceInterface	= NULL;
-		IOCFPlugInInterface	 **cfPluginInterface	= NULL;
-		IOHIDQueueInterface	 **hidQueueInterface	= NULL;
-		io_object_t		 serviceNotification	= 0;
-		CFRunLoopSourceRef	 queueEventSource	= NULL;
-		io_object_t		 theService		= 0;
-		NSMutableDictionary	 *cookieButtonMap	= nil;
-		NSTimer			 *simulateHoldTimer	= nil;
-
-		serviceNotification = (io_object_t)			([serviceDict objectForKey:kHIDRemoteServiceNotification]	? [[serviceDict objectForKey:kHIDRemoteServiceNotification] unsignedIntValue] :   0);
-		theService	    = (io_object_t)			([serviceDict objectForKey:kHIDRemoteService]			? [[serviceDict objectForKey:kHIDRemoteService]		    unsignedIntValue] :   0);
-		queueEventSource    = (CFRunLoopSourceRef)		([serviceDict objectForKey:kHIDRemoteCFRunLoopSource]		? [[serviceDict objectForKey:kHIDRemoteCFRunLoopSource]	    pointerValue]     : NULL);
-		hidQueueInterface   = (IOHIDQueueInterface **)		([serviceDict objectForKey:kHIDRemoteHIDQueueInterface]		? [[serviceDict objectForKey:kHIDRemoteHIDQueueInterface]   pointerValue]     : NULL);
-		hidDeviceInterface  = (IOHIDDeviceInterface122 **)	([serviceDict objectForKey:kHIDRemoteHIDDeviceInterface]	? [[serviceDict objectForKey:kHIDRemoteHIDDeviceInterface]  pointerValue]     : NULL);
-		cfPluginInterface   = (IOCFPlugInInterface **)		([serviceDict objectForKey:kHIDRemoteCFPluginInterface]		? [[serviceDict objectForKey:kHIDRemoteCFPluginInterface]   pointerValue]     : NULL);
-		cookieButtonMap	    = (NSMutableDictionary *)		 [serviceDict objectForKey:kHIDRemoteCookieButtonCodeLUT];
-		simulateHoldTimer   = (NSTimer *)			 [serviceDict objectForKey:kHIDRemoteSimulateHoldEventsTimer];
-		
-		[serviceDict  retain];
-		[_serviceAttribMap removeObjectForKey:serviceValue];
-
-		if (([serviceDict objectForKey:kHIDRemoteAluminumRemoteSupportOnDemand]!=nil) && [[serviceDict objectForKey:kHIDRemoteAluminumRemoteSupportOnDemand] boolValue] && (theService != 0))
-		{
-			// We previously requested the driver to enable Aluminum Remote support for us. Tell it to turn it off again - now that we no longer need it
-			IORegistryEntrySetCFProperty(	(io_registry_entry_t)theService,
-							CFSTR("DisableAluminumRemoteSupportForMe"),
-							[NSDictionary dictionaryWithObjectsAndKeys:
-								[NSNumber numberWithLongLong:(long long)getpid()],	@"pid",
-								[NSNumber numberWithLongLong:(long long)getuid()],	@"uid",
-							nil]);
-		}
-
-		if (([self delegate]!=nil) &&
-		    ([[self delegate] respondsToSelector:@selector(hidRemote:releasedHardwareWithAttributes:)]))
-		{
-			[((NSObject <HIDRemoteDelegate> *)[self delegate]) hidRemote:self releasedHardwareWithAttributes:serviceDict];
-		}
-		
-		if (simulateHoldTimer!=nil)
-		{
-			[simulateHoldTimer invalidate];
-		}
-
-		if (serviceNotification!=0)
-		{
-			IOObjectRelease(serviceNotification);
-		}
-
-		if (queueEventSource!=NULL)
-		{
-			CFRunLoopRemoveSource(	CFRunLoopGetCurrent(),
-						queueEventSource,
-						kCFRunLoopCommonModes);
-		}
-		
-		if ((hidQueueInterface!=NULL) && (cookieButtonMap!=nil))
-		{
-			NSEnumerator *cookieEnum = [cookieButtonMap keyEnumerator];
-			NSNumber *cookie;
-			
-			while ((cookie = [cookieEnum nextObject]) != nil)
-			{
-				if ((*hidQueueInterface)->hasElement(hidQueueInterface, (IOHIDElementCookie) [cookie unsignedIntValue]))
-				{
-					(*hidQueueInterface)->removeElement(hidQueueInterface,
-									    (IOHIDElementCookie) [cookie unsignedIntValue]);
-				}
-			};
-		}
-		
-		if (hidQueueInterface!=NULL)
-		{
-			(*hidQueueInterface)->stop(hidQueueInterface);
-			(*hidQueueInterface)->dispose(hidQueueInterface);
-			(*hidQueueInterface)->Release(hidQueueInterface);
-		}
-		
-		if (hidDeviceInterface!=NULL)
-		{
-			(*hidDeviceInterface)->close(hidDeviceInterface);
-			(*hidDeviceInterface)->Release(hidDeviceInterface);
-		}
-		
-		if (cfPluginInterface!=NULL)
-		{
-			IODestroyPlugInInterface(cfPluginInterface);
-		}
-		
-		if (theService!=0)
-		{
-			IOObjectRelease(theService);
-		}
-
-		[serviceDict release];
-	}
+    NSNumber	    *serviceValue;
+    NSMutableDictionary *serviceDict = NULL;
+
+    if ((serviceValue = [NSNumber numberWithUnsignedInt:(unsigned int)service]) == nil)
+    {
+        return;
+    }
+
+    serviceDict  = [_serviceAttribMap objectForKey:serviceValue];
+
+    if (serviceDict!=nil)
+    {
+        IOHIDDeviceInterface122	 **hidDeviceInterface	= NULL;
+        IOCFPlugInInterface	 **cfPluginInterface	= NULL;
+        IOHIDQueueInterface	 **hidQueueInterface	= NULL;
+        io_object_t		 serviceNotification	= 0;
+        CFRunLoopSourceRef	 queueEventSource	= NULL;
+        io_object_t		 theService		= 0;
+        NSMutableDictionary	 *cookieButtonMap	= nil;
+        NSTimer			 *simulateHoldTimer	= nil;
+
+        serviceNotification = (io_object_t)			([serviceDict objectForKey:kHIDRemoteServiceNotification]	? [[serviceDict objectForKey:kHIDRemoteServiceNotification] unsignedIntValue] :   0);
+        theService	    = (io_object_t)			([serviceDict objectForKey:kHIDRemoteService]			? [[serviceDict objectForKey:kHIDRemoteService]		    unsignedIntValue] :   0);
+        queueEventSource    = (CFRunLoopSourceRef)		([serviceDict objectForKey:kHIDRemoteCFRunLoopSource]		? [[serviceDict objectForKey:kHIDRemoteCFRunLoopSource]	    pointerValue]     : NULL);
+        hidQueueInterface   = (IOHIDQueueInterface **)		([serviceDict objectForKey:kHIDRemoteHIDQueueInterface]		? [[serviceDict objectForKey:kHIDRemoteHIDQueueInterface]   pointerValue]     : NULL);
+        hidDeviceInterface  = (IOHIDDeviceInterface122 **)	([serviceDict objectForKey:kHIDRemoteHIDDeviceInterface]	? [[serviceDict objectForKey:kHIDRemoteHIDDeviceInterface]  pointerValue]     : NULL);
+        cfPluginInterface   = (IOCFPlugInInterface **)		([serviceDict objectForKey:kHIDRemoteCFPluginInterface]		? [[serviceDict objectForKey:kHIDRemoteCFPluginInterface]   pointerValue]     : NULL);
+        cookieButtonMap	    = (NSMutableDictionary *)		 [serviceDict objectForKey:kHIDRemoteCookieButtonCodeLUT];
+        simulateHoldTimer   = (NSTimer *)			 [serviceDict objectForKey:kHIDRemoteSimulateHoldEventsTimer];
+
+        HIDRemoteRetain(serviceDict);
+        [_serviceAttribMap removeObjectForKey:serviceValue];
+
+        if (([serviceDict objectForKey:kHIDRemoteAluminumRemoteSupportOnDemand]!=nil) && [[serviceDict objectForKey:kHIDRemoteAluminumRemoteSupportOnDemand] boolValue] && (theService != 0))
+        {
+            // We previously requested the driver to enable Aluminum Remote support for us. Tell it to turn it off again - now that we no longer need it
+            IORegistryEntrySetCFProperty(	(io_registry_entry_t)theService,
+                            CFSTR("DisableAluminumRemoteSupportForMe"),
+                            (__HIDRemoteBridge CFTypeRef)([NSDictionary dictionaryWithObjectsAndKeys:
+                               [NSNumber numberWithLongLong:(long long)getpid()],	@"pid",
+                               [NSNumber numberWithLongLong:(long long)getuid()],	@"uid",
+                            nil]));
+        }
+
+        if (([self delegate]!=nil) &&
+            ([[self delegate] respondsToSelector:@selector(hidRemote:releasedHardwareWithAttributes:)]))
+        {
+            [((NSObject <HIDRemoteDelegate> *)[self delegate]) hidRemote:self releasedHardwareWithAttributes:serviceDict];
+        }
+
+        if (simulateHoldTimer!=nil)
+        {
+            [simulateHoldTimer invalidate];
+        }
+
+        if (serviceNotification!=0)
+        {
+            IOObjectRelease(serviceNotification);
+        }
+
+        if (queueEventSource!=NULL)
+        {
+            CFRunLoopRemoveSource(	CFRunLoopGetCurrent(),
+                        queueEventSource,
+                        kCFRunLoopCommonModes);
+        }
+
+        if ((hidQueueInterface!=NULL) && (cookieButtonMap!=nil))
+        {
+            NSEnumerator *cookieEnum = [cookieButtonMap keyEnumerator];
+            NSNumber *cookie;
+
+            while ((cookie = [cookieEnum nextObject]) != nil)
+            {
+                if ((*hidQueueInterface)->hasElement(hidQueueInterface, (IOHIDElementCookie) [cookie unsignedIntValue]))
+                {
+                    (*hidQueueInterface)->removeElement(hidQueueInterface,
+                                        (IOHIDElementCookie) [cookie unsignedIntValue]);
+                }
+            };
+        }
+
+        if (hidQueueInterface!=NULL)
+        {
+            (*hidQueueInterface)->stop(hidQueueInterface);
+            (*hidQueueInterface)->dispose(hidQueueInterface);
+            (*hidQueueInterface)->Release(hidQueueInterface);
+        }
+
+        if (hidDeviceInterface!=NULL)
+        {
+            (*hidDeviceInterface)->close(hidDeviceInterface);
+            (*hidDeviceInterface)->Release(hidDeviceInterface);
+        }
+
+        if (cfPluginInterface!=NULL)
+        {
+            IODestroyPlugInInterface(cfPluginInterface);
+        }
+
+        if (theService!=0)
+        {
+            IOObjectRelease(theService);
+        }
+
+        HIDRemoteRelease(serviceDict);
+    }
 }
 
 
 #pragma mark - PRIVATE: HID Event handling
 - (void)_simulateHoldEvent:(NSTimer *)aTimer
 {
-	NSMutableDictionary *hidAttribsDict;
-	NSTimer  *shTimer;
-	NSNumber *shButtonCode;
-	
-	if ((hidAttribsDict = (NSMutableDictionary *)[aTimer userInfo]) != nil)
-	{
-		if (((shTimer	   = [hidAttribsDict objectForKey:kHIDRemoteSimulateHoldEventsTimer]) != nil) &&
-		    ((shButtonCode = [hidAttribsDict objectForKey:kHIDRemoteSimulateHoldEventsOriginButtonCode]) != nil)) 
-		{
-			[shTimer invalidate];
-			[hidAttribsDict removeObjectForKey:kHIDRemoteSimulateHoldEventsTimer];
-
-			[self _sendButtonCode:(((HIDRemoteButtonCode)[shButtonCode unsignedIntValue])|kHIDRemoteButtonCodeHoldMask) isPressed:YES hidAttribsDict:hidAttribsDict];
-		}
-	}
+    NSMutableDictionary *hidAttribsDict;
+    NSTimer  *shTimer;
+    NSNumber *shButtonCode;
+
+    if ((hidAttribsDict = (NSMutableDictionary *)[aTimer userInfo]) != nil)
+    {
+        if (((shTimer	   = [hidAttribsDict objectForKey:kHIDRemoteSimulateHoldEventsTimer]) != nil) &&
+            ((shButtonCode = [hidAttribsDict objectForKey:kHIDRemoteSimulateHoldEventsOriginButtonCode]) != nil))
+        {
+            [shTimer invalidate];
+            [hidAttribsDict removeObjectForKey:kHIDRemoteSimulateHoldEventsTimer];
+
+            [self _sendButtonCode:(((HIDRemoteButtonCode)[shButtonCode unsignedIntValue])|kHIDRemoteButtonCodeHoldMask) isPressed:YES hidAttribsDict:hidAttribsDict];
+        }
+    }
 }
 
 - (void)_handleButtonCode:(HIDRemoteButtonCode)buttonCode isPressed:(BOOL)isPressed hidAttribsDict:(NSMutableDictionary *)hidAttribsDict
 {
-	switch (buttonCode)
-	{
-		case kHIDRemoteButtonCodeIDChanged:
-			// Do nothing, this is handled seperately
-		break;
-
-		case kHIDRemoteButtonCodeUp:
-		case kHIDRemoteButtonCodeDown:
-			if (_simulateHoldEvents)
-			{
-				NSTimer  *shTimer = nil;
-				NSNumber *shButtonCode = nil;
-
-				[[hidAttribsDict objectForKey:kHIDRemoteSimulateHoldEventsTimer] invalidate];
-
-				if (isPressed)
-				{
-					[hidAttribsDict setObject:[NSNumber numberWithUnsignedInt:buttonCode] forKey:kHIDRemoteSimulateHoldEventsOriginButtonCode];
-				
-					if ((shTimer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:0.7] interval:0.1 target:self selector:@selector(_simulateHoldEvent:) userInfo:hidAttribsDict repeats:NO]) != nil)
-					{
-						[hidAttribsDict setObject:shTimer forKey:kHIDRemoteSimulateHoldEventsTimer];
-					
-						// Using CFRunLoopAddTimer instead of [[NSRunLoop currentRunLoop] addTimer:.. for consistency with run loop modes.
-						// The kCFRunLoopCommonModes counterpart NSRunLoopCommonModes is only available in 10.5 and later, whereas this code
-						// is designed to be also compatible with 10.4. CFRunLoopTimerRef is "toll-free-bridged" with NSTimer since 10.0.
-						CFRunLoopAddTimer(CFRunLoopGetCurrent(), (CFRunLoopTimerRef)shTimer, kCFRunLoopCommonModes);
-						
-						[shTimer release];
-
-						break;
-					}
-				}
-				else
-				{
-					shTimer	     = [hidAttribsDict objectForKey:kHIDRemoteSimulateHoldEventsTimer];
-					shButtonCode = [hidAttribsDict objectForKey:kHIDRemoteSimulateHoldEventsOriginButtonCode];
-				
-					if ((shTimer!=nil) && (shButtonCode!=nil))
-					{
-						[self _sendButtonCode:(HIDRemoteButtonCode)[shButtonCode unsignedIntValue] isPressed:YES hidAttribsDict:hidAttribsDict];
-						[self _sendButtonCode:(HIDRemoteButtonCode)[shButtonCode unsignedIntValue] isPressed:NO hidAttribsDict:hidAttribsDict];
-					}
-					else
-					{
-						if (shButtonCode!=nil)
-						{
-							[self _sendButtonCode:(((HIDRemoteButtonCode)[shButtonCode unsignedIntValue])|kHIDRemoteButtonCodeHoldMask) isPressed:NO hidAttribsDict:hidAttribsDict];
-						}
-					}
-				}
-
-				[hidAttribsDict removeObjectForKey:kHIDRemoteSimulateHoldEventsTimer];
-				[hidAttribsDict removeObjectForKey:kHIDRemoteSimulateHoldEventsOriginButtonCode];
-					
-				break;
-			}
-		
-		default:
-			[self _sendButtonCode:buttonCode isPressed:isPressed hidAttribsDict:hidAttribsDict];
-		break;
-	}
+    switch (buttonCode)
+    {
+        case kHIDRemoteButtonCodeIDChanged:
+            // Do nothing, this is handled seperately
+        break;
+
+        case kHIDRemoteButtonCodeUp:
+        case kHIDRemoteButtonCodeDown:
+            if (_simulateHoldEvents)
+            {
+                NSTimer  *shTimer = nil;
+                NSNumber *shButtonCode = nil;
+
+                [[hidAttribsDict objectForKey:kHIDRemoteSimulateHoldEventsTimer] invalidate];
+
+                if (isPressed)
+                {
+                    [hidAttribsDict setObject:[NSNumber numberWithUnsignedInt:buttonCode] forKey:kHIDRemoteSimulateHoldEventsOriginButtonCode];
+
+                    if ((shTimer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:0.7] interval:0.1 target:self selector:@selector(_simulateHoldEvent:) userInfo:hidAttribsDict repeats:NO]) != nil)
+                    {
+                        [hidAttribsDict setObject:shTimer forKey:kHIDRemoteSimulateHoldEventsTimer];
+
+                        // Using CFRunLoopAddTimer instead of [[NSRunLoop currentRunLoop] addTimer:.. for consistency with run loop modes.
+                        // The kCFRunLoopCommonModes counterpart NSRunLoopCommonModes is only available in 10.5 and later, whereas this code
+                        // is designed to be also compatible with 10.4. CFRunLoopTimerRef is "toll-free-bridged" with NSTimer since 10.0.
+                        CFRunLoopAddTimer(CFRunLoopGetCurrent(), (CFRunLoopTimerRef)shTimer, kCFRunLoopCommonModes);
+
+                        HIDRemoteRelease(shTimer);
+
+                        break;
+                    }
+                }
+                else
+                {
+                    shTimer	     = [hidAttribsDict objectForKey:kHIDRemoteSimulateHoldEventsTimer];
+                    shButtonCode = [hidAttribsDict objectForKey:kHIDRemoteSimulateHoldEventsOriginButtonCode];
+
+                    if ((shTimer!=nil) && (shButtonCode!=nil))
+                    {
+                        [self _sendButtonCode:(HIDRemoteButtonCode)[shButtonCode unsignedIntValue] isPressed:YES hidAttribsDict:hidAttribsDict];
+                        [self _sendButtonCode:(HIDRemoteButtonCode)[shButtonCode unsignedIntValue] isPressed:NO hidAttribsDict:hidAttribsDict];
+                    }
+                    else
+                    {
+                        if (shButtonCode!=nil)
+                        {
+                            [self _sendButtonCode:(((HIDRemoteButtonCode)[shButtonCode unsignedIntValue])|kHIDRemoteButtonCodeHoldMask) isPressed:NO hidAttribsDict:hidAttribsDict];
+                        }
+                    }
+                }
+
+                [hidAttribsDict removeObjectForKey:kHIDRemoteSimulateHoldEventsTimer];
+                [hidAttribsDict removeObjectForKey:kHIDRemoteSimulateHoldEventsOriginButtonCode];
+
+                break;
+            }
+
+        default:
+            [self _sendButtonCode:buttonCode isPressed:isPressed hidAttribsDict:hidAttribsDict];
+        break;
+    }
 }
 
 - (void)_sendButtonCode:(HIDRemoteButtonCode)buttonCode isPressed:(BOOL)isPressed hidAttribsDict:(NSMutableDictionary *)hidAttribsDict
 {
-	if (([self delegate]!=nil) &&
-	    ([[self delegate] respondsToSelector:@selector(hidRemote:eventWithButton:isPressed:fromHardwareWithAttributes:)]))
-	{
-		switch (buttonCode & (~kHIDRemoteButtonCodeAluminumMask))
-		{
-			case kHIDRemoteButtonCodePlay:
-			case kHIDRemoteButtonCodeCenter:
-				if (buttonCode & kHIDRemoteButtonCodeAluminumMask)
-				{
-					_lastSeenModel         = kHIDRemoteModelAluminum;
-					_lastSeenModelRemoteID = _lastSeenRemoteID;
-				}
-				else
-				{
-					switch ((HIDRemoteAluminumRemoteSupportLevel)[[hidAttribsDict objectForKey:kHIDRemoteAluminumRemoteSupportLevel] intValue])
-					{
-						case kHIDRemoteAluminumRemoteSupportLevelNone:
-						case kHIDRemoteAluminumRemoteSupportLevelEmulation:
-							// Remote type can't be determined by just the Center button press
-						break;
-
-						case kHIDRemoteAluminumRemoteSupportLevelNative:
-							// Remote type can be safely determined by just the Center button press
-							if (((_lastSeenModel == kHIDRemoteModelAluminum) && (_lastSeenModelRemoteID != _lastSeenRemoteID)) ||
-							     (_lastSeenModel == kHIDRemoteModelUndetermined))
-							{
-								_lastSeenModel = kHIDRemoteModelWhitePlastic;
-							}
-						break;
-					}
-				}
-			break;
-		}
-		
-		// As soon as we have received a code that's unique to the Aluminum Remote, we can tell kHIDRemoteButtonCodePlayHold and kHIDRemoteButtonCodeCenterHold apart.
-		// Prior to that, a long press of the new "Play" button will be submitted as a "kHIDRemoteButtonCodeCenterHold", not a "kHIDRemoteButtonCodePlayHold" code.
-		if ((buttonCode == kHIDRemoteButtonCodeCenterHold) && (_lastSeenModel == kHIDRemoteModelAluminum))
-		{
-			buttonCode = kHIDRemoteButtonCodePlayHold;
-		}
-	
-		[((NSObject <HIDRemoteDelegate> *)[self delegate]) hidRemote:self eventWithButton:(buttonCode & (~kHIDRemoteButtonCodeAluminumMask)) isPressed:isPressed fromHardwareWithAttributes:hidAttribsDict];
-	}
+    if (([self delegate]!=nil) &&
+        ([[self delegate] respondsToSelector:@selector(hidRemote:eventWithButton:isPressed:fromHardwareWithAttributes:)]))
+    {
+        switch (buttonCode & (~kHIDRemoteButtonCodeAluminumMask))
+        {
+            case kHIDRemoteButtonCodePlay:
+            case kHIDRemoteButtonCodeCenter:
+                if (buttonCode & kHIDRemoteButtonCodeAluminumMask)
+                {
+                    _lastSeenModel         = kHIDRemoteModelAluminum;
+                    _lastSeenModelRemoteID = _lastSeenRemoteID;
+                }
+                else
+                {
+                    switch ((HIDRemoteAluminumRemoteSupportLevel)[[hidAttribsDict objectForKey:kHIDRemoteAluminumRemoteSupportLevel] intValue])
+                    {
+                        case kHIDRemoteAluminumRemoteSupportLevelNone:
+                        case kHIDRemoteAluminumRemoteSupportLevelEmulation:
+                            // Remote type can't be determined by just the Center button press
+                        break;
+
+                        case kHIDRemoteAluminumRemoteSupportLevelNative:
+                            // Remote type can be safely determined by just the Center button press
+                            if (((_lastSeenModel == kHIDRemoteModelAluminum) && (_lastSeenModelRemoteID != _lastSeenRemoteID)) ||
+                                 (_lastSeenModel == kHIDRemoteModelUndetermined))
+                            {
+                                _lastSeenModel = kHIDRemoteModelWhitePlastic;
+                            }
+                        break;
+                    }
+                }
+            break;
+        }
+
+        // As soon as we have received a code that's unique to the Aluminum Remote, we can tell kHIDRemoteButtonCodePlayHold and kHIDRemoteButtonCodeCenterHold apart.
+        // Prior to that, a long press of the new "Play" button will be submitted as a "kHIDRemoteButtonCodeCenterHold", not a "kHIDRemoteButtonCodePlayHold" code.
+        if ((buttonCode == kHIDRemoteButtonCodeCenterHold) && (_lastSeenModel == kHIDRemoteModelAluminum))
+        {
+            buttonCode = kHIDRemoteButtonCodePlayHold;
+        }
+
+        [((NSObject <HIDRemoteDelegate> *)[self delegate]) hidRemote:self eventWithButton:(buttonCode & (~kHIDRemoteButtonCodeAluminumMask)) isPressed:isPressed fromHardwareWithAttributes:hidAttribsDict];
+    }
 }
 
 - (void)_hidEventFor:(io_service_t)hidDevice from:(IOHIDQueueInterface **)interface withResult:(IOReturn)result
 {
-	NSMutableDictionary *hidAttribsDict = [[[_serviceAttribMap objectForKey:[NSNumber numberWithUnsignedInt:(unsigned int)hidDevice]] retain] autorelease];
-	
-	if (hidAttribsDict!=nil)
-	{
-		IOHIDQueueInterface **queueInterface  = NULL;
-		
-		queueInterface  = [[hidAttribsDict objectForKey:kHIDRemoteHIDQueueInterface] pointerValue];
-		
-		if (interface == queueInterface)
-		{
-			NSNumber	    *lastButtonPressedNumber = nil;
-			HIDRemoteButtonCode  lastButtonPressed = kHIDRemoteButtonCodeNone;
-			NSMutableDictionary *cookieButtonMap = nil;
-			
-			cookieButtonMap  = [hidAttribsDict objectForKey:kHIDRemoteCookieButtonCodeLUT];
-
-			if ((lastButtonPressedNumber = [hidAttribsDict objectForKey:kHIDRemoteLastButtonPressed]) != nil)
-			{
-				lastButtonPressed = [lastButtonPressedNumber unsignedIntValue];
-			}
-
-			while (result == kIOReturnSuccess)
-			{
-				IOHIDEventStruct hidEvent;
-				AbsoluteTime supportedTime = { 0,0 };
-			
-				result = (*queueInterface)->getNextEvent(	queueInterface,
-										&hidEvent,
-										supportedTime,
-										0);
-									
-				if (result == kIOReturnSuccess)
-				{
-					NSNumber *buttonCodeNumber = [cookieButtonMap objectForKey:[NSNumber numberWithUnsignedInt:(unsigned int) hidEvent.elementCookie]];
-					
-					#ifdef _HIDREMOTE_EXTENSIONS
-						// Debug logging code
-						#define _HIDREMOTE_EXTENSIONS_SECTION 5
-						#include "HIDRemoteAdditions.h"
-						#undef _HIDREMOTE_EXTENSIONS_SECTION
-					#endif /* _HIDREMOTE_EXTENSIONS */
-					
-					if (buttonCodeNumber!=nil)
-					{
-						HIDRemoteButtonCode buttonCode = [buttonCodeNumber unsignedIntValue];
-					
-						if (hidEvent.value == 0)
-						{
-							if (buttonCode == lastButtonPressed)
-							{
-								[self _handleButtonCode:lastButtonPressed isPressed:NO hidAttribsDict:hidAttribsDict];
-								lastButtonPressed = kHIDRemoteButtonCodeNone;
-							}
-						}
-
-						if (hidEvent.value != 0)
-						{
-							if (lastButtonPressed != kHIDRemoteButtonCodeNone)
-							{
-								[self _handleButtonCode:lastButtonPressed isPressed:NO hidAttribsDict:hidAttribsDict];
-								// lastButtonPressed = kHIDRemoteButtonCodeNone;
-							}
-
-							if (buttonCode == kHIDRemoteButtonCodeIDChanged)
-							{
-								if (([self delegate]!=nil) &&
-								    ([[self delegate] respondsToSelector:@selector(hidRemote:remoteIDChangedOldID:newID:forHardwareWithAttributes:)]))
-								{
-									[((NSObject <HIDRemoteDelegate> *)[self delegate]) hidRemote:self remoteIDChangedOldID:_lastSeenRemoteID newID:hidEvent.value forHardwareWithAttributes:hidAttribsDict];
-								}
-							
-								_lastSeenRemoteID = hidEvent.value;
-								_lastSeenModel	  = kHIDRemoteModelUndetermined;
-							}
-							
-							[self _handleButtonCode:buttonCode isPressed:YES hidAttribsDict:hidAttribsDict];
-							lastButtonPressed = buttonCode;
-						}
-					}
-				}
-			};
-		
-			[hidAttribsDict setObject:[NSNumber numberWithUnsignedInt:lastButtonPressed] forKey:kHIDRemoteLastButtonPressed];
-		}
-		
-		#ifdef _HIDREMOTE_EXTENSIONS
-			// Debug logging code
-			#define _HIDREMOTE_EXTENSIONS_SECTION 6
-			#include "HIDRemoteAdditions.h"
-			#undef _HIDREMOTE_EXTENSIONS_SECTION
-		#endif /* _HIDREMOTE_EXTENSIONS */
-	}
+    NSMutableDictionary *hidAttribsDict = HIDRemoteAutoreleased(HIDRemoteRetained([_serviceAttribMap objectForKey:[NSNumber numberWithUnsignedInt:(unsigned int)hidDevice]]));
+
+    if (hidAttribsDict!=nil)
+    {
+        IOHIDQueueInterface **queueInterface  = NULL;
+
+        queueInterface  = [[hidAttribsDict objectForKey:kHIDRemoteHIDQueueInterface] pointerValue];
+
+        if (interface == queueInterface)
+        {
+            NSNumber	    *lastButtonPressedNumber = nil;
+            HIDRemoteButtonCode  lastButtonPressed = kHIDRemoteButtonCodeNone;
+            NSMutableDictionary *cookieButtonMap = nil;
+
+            cookieButtonMap  = [hidAttribsDict objectForKey:kHIDRemoteCookieButtonCodeLUT];
+
+            if ((lastButtonPressedNumber = [hidAttribsDict objectForKey:kHIDRemoteLastButtonPressed]) != nil)
+            {
+                lastButtonPressed = [lastButtonPressedNumber unsignedIntValue];
+            }
+
+            while (result == kIOReturnSuccess)
+            {
+                IOHIDEventStruct hidEvent;
+                AbsoluteTime supportedTime = { 0,0 };
+
+                result = (*queueInterface)->getNextEvent(	queueInterface,
+                                        &hidEvent,
+                                        supportedTime,
+                                        0);
+
+                if (result == kIOReturnSuccess)
+                {
+                    NSNumber *buttonCodeNumber = [cookieButtonMap objectForKey:[NSNumber numberWithUnsignedInt:(unsigned int) hidEvent.elementCookie]];
+
+                    #ifdef _HIDREMOTE_EXTENSIONS
+                        // Debug logging code
+                        #define _HIDREMOTE_EXTENSIONS_SECTION 5
+                        #include "HIDRemoteAdditions.h"
+                        #undef _HIDREMOTE_EXTENSIONS_SECTION
+                    #endif /* _HIDREMOTE_EXTENSIONS */
+
+                    if (buttonCodeNumber!=nil)
+                    {
+                        HIDRemoteButtonCode buttonCode = [buttonCodeNumber unsignedIntValue];
+
+                        if (hidEvent.value == 0)
+                        {
+                            if (buttonCode == lastButtonPressed)
+                            {
+                                [self _handleButtonCode:lastButtonPressed isPressed:NO hidAttribsDict:hidAttribsDict];
+                                lastButtonPressed = kHIDRemoteButtonCodeNone;
+                            }
+                        }
+
+                        if (hidEvent.value != 0)
+                        {
+                            if (lastButtonPressed != kHIDRemoteButtonCodeNone)
+                            {
+                                [self _handleButtonCode:lastButtonPressed isPressed:NO hidAttribsDict:hidAttribsDict];
+                                // lastButtonPressed = kHIDRemoteButtonCodeNone;
+                            }
+
+                            if (buttonCode == kHIDRemoteButtonCodeIDChanged)
+                            {
+                                if (([self delegate]!=nil) &&
+                                    ([[self delegate] respondsToSelector:@selector(hidRemote:remoteIDChangedOldID:newID:forHardwareWithAttributes:)]))
+                                {
+                                    [((NSObject <HIDRemoteDelegate> *)[self delegate]) hidRemote:self remoteIDChangedOldID:_lastSeenRemoteID newID:hidEvent.value forHardwareWithAttributes:hidAttribsDict];
+                                }
+
+                                _lastSeenRemoteID = hidEvent.value;
+                                _lastSeenModel	  = kHIDRemoteModelUndetermined;
+                            }
+
+                            [self _handleButtonCode:buttonCode isPressed:YES hidAttribsDict:hidAttribsDict];
+                            lastButtonPressed = buttonCode;
+                        }
+                    }
+                }
+            };
+
+            [hidAttribsDict setObject:[NSNumber numberWithUnsignedInt:lastButtonPressed] forKey:kHIDRemoteLastButtonPressed];
+        }
+
+        #ifdef _HIDREMOTE_EXTENSIONS
+            // Debug logging code
+            #define _HIDREMOTE_EXTENSIONS_SECTION 6
+            #include "HIDRemoteAdditions.h"
+            #undef _HIDREMOTE_EXTENSIONS_SECTION
+        #endif /* _HIDREMOTE_EXTENSIONS */
+    }
 }
 
 #pragma mark - PRIVATE: Notification handling
 - (void)_serviceMatching:(io_iterator_t)iterator
 {
-	io_object_t matchingService = 0;
+    io_object_t matchingService = 0;
 
-	while ((matchingService = IOIteratorNext(iterator)) != 0)
-	{
-		[self _setupService:matchingService];
+    while ((matchingService = IOIteratorNext(iterator)) != 0)
+    {
+        [self _setupService:matchingService];
 
-		IOObjectRelease(matchingService);
-	};
+        IOObjectRelease(matchingService);
+    };
 }
 
 - (void)_serviceNotificationFor:(io_service_t)service messageType:(natural_t)messageType messageArgument:(void *)messageArgument
 {
-	if (messageType == kIOMessageServiceIsTerminated)
-	{
-		[self _destructService:service];
-	}
+    if (messageType == kIOMessageServiceIsTerminated)
+    {
+        [self _destructService:service];
+    }
 }
 
 - (void)_updateSessionInformation
 {
-	NSArray *consoleUsersArray;
-	io_service_t rootService;
-	
-	if (_masterPort==0) { return; }
-	
-	if ((rootService = IORegistryGetRootEntry(_masterPort)) != 0)
-	{
-		if ((consoleUsersArray = (NSArray *)IORegistryEntryCreateCFProperty((io_registry_entry_t)rootService, CFSTR("IOConsoleUsers"), kCFAllocatorDefault, 0)) != nil)
-		{
-			if ([consoleUsersArray isKindOfClass:[NSArray class]])	// Be careful - ensure this really is an array
-			{
-				NSEnumerator *consoleUsersEnum; // I *love* Obj-C2's fast enumerators, but we need to stay compatible with 10.4 :-/
-				
-				if ((consoleUsersEnum = [consoleUsersArray objectEnumerator]) != nil)
-				{
-					UInt64 secureEventInputPIDSum = 0;
-					uid_t frontUserSession = 0;
-					BOOL screenIsLocked = NO;
-					NSDictionary *consoleUserDict;
-					
-					while ((consoleUserDict = [consoleUsersEnum nextObject]) != nil)
-					{
-						if ([consoleUserDict isKindOfClass:[NSDictionary class]]) // Be careful - ensure this really is a dictionary
-						{
-							NSNumber *secureInputPID;
-							NSNumber *onConsole;
-							NSNumber *userID;
-							NSNumber *screenIsLockedBool;
-						
-							if ((secureInputPID = [consoleUserDict objectForKey:@"kCGSSessionSecureInputPID"]) != nil)
-							{
-								if ([secureInputPID isKindOfClass:[NSNumber class]])
-								{
-									secureEventInputPIDSum += ((UInt64) [secureInputPID intValue]);
-								}
-							}
-							
-							if (((onConsole = [consoleUserDict objectForKey:@"kCGSSessionOnConsoleKey"]) != nil) &&
-							    ((userID    = [consoleUserDict objectForKey:@"kCGSSessionUserIDKey"]) != nil))
-							{
-								if ([onConsole isKindOfClass:[NSNumber class]] && [userID isKindOfClass:[NSNumber class]])
-								{
-									if ([onConsole boolValue])
-									{
-										frontUserSession = (uid_t) [userID intValue];
-									}
-								}
-							}
-							
-							if ((screenIsLockedBool = [consoleUserDict objectForKey:@"CGSSessionScreenIsLocked"]) != nil)
-							{
-								if ([screenIsLockedBool isKindOfClass:[NSNumber class]])
-								{
-									screenIsLocked = [screenIsLockedBool boolValue];
-								}
-							}
-						}
-					}
-
-					_lastSecureEventInputPIDSum = secureEventInputPIDSum;
-					_lastFrontUserSession	    = frontUserSession;
-					_lastScreenIsLocked	    = screenIsLocked;
-				}
-			}
-		
-			CFRelease((CFTypeRef)consoleUsersArray);
-		}
-		
-		IOObjectRelease((io_object_t) rootService);
-	}
+    NSArray *consoleUsersArray;
+    io_service_t rootService;
+
+    if (_masterPort==0) { return; }
+
+    if ((rootService = IORegistryGetRootEntry(_masterPort)) != 0)
+    {
+        if ((consoleUsersArray = (__HIDRemoteBridge NSArray *)IORegistryEntryCreateCFProperty((io_registry_entry_t)rootService, CFSTR("IOConsoleUsers"), kCFAllocatorDefault, 0)) != nil)
+        {
+            if ([consoleUsersArray isKindOfClass:[NSArray class]])	// Be careful - ensure this really is an array
+            {
+                NSEnumerator *consoleUsersEnum; // I *love* Obj-C2's fast enumerators, but we need to stay compatible with 10.4 :-/
+
+                if ((consoleUsersEnum = [consoleUsersArray objectEnumerator]) != nil)
+                {
+                    UInt64 secureEventInputPIDSum = 0;
+                    uid_t frontUserSession = 0;
+                    BOOL screenIsLocked = NO;
+                    NSDictionary *consoleUserDict;
+
+                    while ((consoleUserDict = [consoleUsersEnum nextObject]) != nil)
+                    {
+                        if ([consoleUserDict isKindOfClass:[NSDictionary class]]) // Be careful - ensure this really is a dictionary
+                        {
+                            NSNumber *secureInputPID;
+                            NSNumber *onConsole;
+                            NSNumber *userID;
+                            NSNumber *screenIsLockedBool;
+
+                            if ((secureInputPID = [consoleUserDict objectForKey:@"kCGSSessionSecureInputPID"]) != nil)
+                            {
+                                if ([secureInputPID isKindOfClass:[NSNumber class]])
+                                {
+                                    secureEventInputPIDSum += ((UInt64) [secureInputPID intValue]);
+                                }
+                            }
+
+                            if (((onConsole = [consoleUserDict objectForKey:@"kCGSSessionOnConsoleKey"]) != nil) &&
+                                ((userID    = [consoleUserDict objectForKey:@"kCGSSessionUserIDKey"]) != nil))
+                            {
+                                if ([onConsole isKindOfClass:[NSNumber class]] && [userID isKindOfClass:[NSNumber class]])
+                                {
+                                    if ([onConsole boolValue])
+                                    {
+                                        frontUserSession = (uid_t) [userID intValue];
+                                    }
+                                }
+                            }
+
+                            if ((screenIsLockedBool = [consoleUserDict objectForKey:@"CGSSessionScreenIsLocked"]) != nil)
+                            {
+                                if ([screenIsLockedBool isKindOfClass:[NSNumber class]])
+                                {
+                                    screenIsLocked = [screenIsLockedBool boolValue];
+                                }
+                            }
+                        }
+                    }
+
+                    _lastSecureEventInputPIDSum = secureEventInputPIDSum;
+                    _lastFrontUserSession	    = frontUserSession;
+                    _lastScreenIsLocked	    = screenIsLocked;
+                }
+            }
+
+            CFRelease((CFTypeRef)consoleUsersArray);
+        }
+
+        IOObjectRelease((io_object_t) rootService);
+    }
 }
 
 - (void)_silentRestart
 {
-	if ((_mode == kHIDRemoteModeExclusive) || (_mode == kHIDRemoteModeExclusiveAuto))
-	{
-		HIDRemoteMode restartInMode = _mode;
-		unsigned checkActiveRemoteControlCount = [self activeRemoteControlCount];
-		
-		// Only restart when we already have active remote controls - to avoid race conditions with other applications using kHIDRemoteModeExclusive mode (new in V1.2.1)
-		if (checkActiveRemoteControlCount > 0)
-		{
-			_isRestarting = YES;
-			[self stopRemoteControl];
-			[self startRemoteControl:restartInMode];
-			_isRestarting = NO;
-			
-			// Check whether we lost a remote control due to restarting/secure input change notification handling (new in V1.2.1)
-			if (checkActiveRemoteControlCount != [self activeRemoteControlCount])
-			{
-				// Log message
-				NSLog(@"Lost access (mode %d) to %d IR Remote Receiver(s) after handling SecureInput change notification - please quit other apps trying to use the Remote exclusively", restartInMode, checkActiveRemoteControlCount);
-			}
-		}
-	}
+    if ((_mode == kHIDRemoteModeExclusive) || (_mode == kHIDRemoteModeExclusiveAuto))
+    {
+        HIDRemoteMode restartInMode = _mode;
+        unsigned checkActiveRemoteControlCount = [self activeRemoteControlCount];
+
+        // Only restart when we already have active remote controls - to avoid race conditions with other applications using kHIDRemoteModeExclusive mode (new in V1.2.1)
+        if (checkActiveRemoteControlCount > 0)
+        {
+            _isRestarting = YES;
+            [self stopRemoteControl];
+            [self startRemoteControl:restartInMode];
+            _isRestarting = NO;
+
+            // Check whether we lost a remote control due to restarting/secure input change notification handling (new in V1.2.1)
+            if (checkActiveRemoteControlCount != [self activeRemoteControlCount])
+            {
+                // Log message
+                NSLog(@"Lost access (mode %d) to %d IR Remote Receiver(s) after handling SecureInput change notification - please quit other apps trying to use the Remote exclusively", restartInMode, checkActiveRemoteControlCount);
+            }
+        }
+    }
 }
 
 - (void)_secureInputNotificationFor:(io_service_t)service messageType:(natural_t)messageType messageArgument:(void *)messageArgument
 {
-	if (messageType == kIOMessageServiceBusyStateChange)
-	{
-		UInt64 old_lastSecureEventInputPIDSum = _lastSecureEventInputPIDSum;
-		uid_t  old_lastFrontUserSession = _lastFrontUserSession;
-		BOOL   old_lastScreenIsLocked = _lastScreenIsLocked;
-		
-		[self _updateSessionInformation];
-		
-		if (((old_lastSecureEventInputPIDSum != _lastSecureEventInputPIDSum) ||
-		     (old_lastFrontUserSession != _lastFrontUserSession) ||
-		     (old_lastScreenIsLocked != _lastScreenIsLocked)) && _secureEventInputWorkAround)
-		{
-			[self _silentRestart];
-		}
-	}
+    if (messageType == kIOMessageServiceBusyStateChange)
+    {
+        UInt64 old_lastSecureEventInputPIDSum = _lastSecureEventInputPIDSum;
+        uid_t  old_lastFrontUserSession = _lastFrontUserSession;
+        BOOL   old_lastScreenIsLocked = _lastScreenIsLocked;
+
+        [self _updateSessionInformation];
+
+        if (((old_lastSecureEventInputPIDSum != _lastSecureEventInputPIDSum) ||
+             (old_lastFrontUserSession != _lastFrontUserSession) ||
+             (old_lastScreenIsLocked != _lastScreenIsLocked)) && _secureEventInputWorkAround)
+        {
+            [self _silentRestart];
+        }
+    }
 }
 
 - (void)_computerDidWake:(NSNotification *)aNotification
 {
-	// Work around for a bug in 10.8, where exclusive connections may be degraded to shared connections after a sleep/wakeup cycle (credit: Paul Duggan from Galaxy Software)
-	#ifdef NSAppKitVersionNumber10_8
-	if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_8)
-	#else
-	if (NSAppKitVersionNumber >= 1187)
-	#endif
-	{
-		#ifdef HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING
-		if ([self respondsToSelector:@selector(performSelector:onThread:withObject:waitUntilDone:)]) // OS X 10.5+ only
-		{
-			if ([NSThread currentThread] != _runOnThread)
-			{
-				[self performSelector:@selector(_computerDidWake:) onThread:_runOnThread withObject:aNotification waitUntilDone:NO];
-				return;
-			}
-		}
-		#endif
-
-		[self _silentRestart];
-	}
+    // Work around for a bug in 10.8, where exclusive connections may be degraded to shared connections after a sleep/wakeup cycle (credit: Paul Duggan from Galaxy Software)
+    #ifdef NSAppKitVersionNumber10_8
+    if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_8)
+    #else
+    if (NSAppKitVersionNumber >= 1187)
+    #endif
+    {
+        #if HIDREMOTE_THREADSAFETY_HARDENED_NOTIFICATION_HANDLING
+        if ([self respondsToSelector:@selector(performSelector:onThread:withObject:waitUntilDone:)]) // OS X 10.5+ only
+        {
+            if ([NSThread currentThread] != _runOnThread)
+            {
+                [self performSelector:@selector(_computerDidWake:) onThread:_runOnThread withObject:aNotification waitUntilDone:NO];
+                return;
+            }
+        }
+        #endif
+
+        [self _silentRestart];
+    }
 }
 
 @end
 
 #pragma mark - PRIVATE: IOKitLib Callbacks
 
-static void HIDEventCallback(	void * target, 
-				IOReturn result,
-				void * refCon,
-				void * sender)
+static void HIDEventCallback(	void * target,
+                IOReturn result,
+                void * refCon,
+                void * sender)
 {
-	HIDRemote		*hidRemote = (HIDRemote *)refCon;
-	NSAutoreleasePool	*pool	   = [[NSAutoreleasePool alloc] init];
+    HIDRemote		*hidRemote = (__HIDRemoteBridge HIDRemote *)refCon;
 
-	[hidRemote _hidEventFor:(io_service_t)((intptr_t)target) from:(IOHIDQueueInterface**)sender withResult:(IOReturn)result];
+    HIDRemoteAutoreleasePoolOpen();
 
-	[pool release];
+    [hidRemote _hidEventFor:(io_service_t)((intptr_t)target) from:(IOHIDQueueInterface**)sender withResult:(IOReturn)result];
+
+    HIDRemoteAutoreleasePoolClose();
 }
 
 
 static void ServiceMatchingCallback(	void *refCon,
-					io_iterator_t iterator)
+                    io_iterator_t iterator)
 {
-	HIDRemote		*hidRemote = (HIDRemote *)refCon;
-	NSAutoreleasePool	*pool	   = [[NSAutoreleasePool alloc] init];
+    HIDRemote		*hidRemote = (__HIDRemoteBridge HIDRemote *)refCon;
+
+    HIDRemoteAutoreleasePoolOpen();
 
-	[hidRemote _serviceMatching:iterator];
+    [hidRemote _serviceMatching:iterator];
 
-	[pool release];
+    HIDRemoteAutoreleasePoolClose();
 }
 
 static void ServiceNotificationCallback(void *		refCon,
-					io_service_t 	service,
-					natural_t 	messageType,
-					void *		messageArgument)
+                    io_service_t 	service,
+                    natural_t 	messageType,
+                    void *		messageArgument)
 {
-	HIDRemote		*hidRemote = (HIDRemote *)refCon;
-	NSAutoreleasePool	*pool     = [[NSAutoreleasePool alloc] init];
-	
-	[hidRemote _serviceNotificationFor:service
-			       messageType:messageType
-			   messageArgument:messageArgument];
-
-	[pool release];
+    HIDRemote		*hidRemote = (__HIDRemoteBridge HIDRemote *)refCon;
+
+    HIDRemoteAutoreleasePoolOpen();
+
+    [hidRemote _serviceNotificationFor:service
+                   messageType:messageType
+               messageArgument:messageArgument];
+
+    HIDRemoteAutoreleasePoolClose();
 }
 
 static void SecureInputNotificationCallback(	void *		refCon,
-						io_service_t 	service,
-						natural_t 	messageType,
-						void *		messageArgument)
+                        io_service_t 	service,
+                        natural_t 	messageType,
+                        void *		messageArgument)
 {
-	HIDRemote		*hidRemote = (HIDRemote *)refCon;
-	NSAutoreleasePool	*pool     = [[NSAutoreleasePool alloc] init];
-	
-	[hidRemote _secureInputNotificationFor:service
-				   messageType:messageType
-			       messageArgument:messageArgument];
-
-	[pool release];
+    HIDRemote		*hidRemote = (__HIDRemoteBridge HIDRemote *)refCon;
+
+    HIDRemoteAutoreleasePoolOpen();
+
+    [hidRemote _secureInputNotificationFor:service
+                   messageType:messageType
+                   messageArgument:messageArgument];
+
+    HIDRemoteAutoreleasePoolClose();
 }
 
 // Attribute dictionary keys