Index: SapphireFrappliance/Info.plist
===================================================================
--- SapphireFrappliance/Info.plist	(Revision 493)
+++ SapphireFrappliance/Info.plist	(Arbeitskopie)
@@ -25,10 +25,30 @@
 	<key>FRApplianceIconReflectionOffset</key>
 	<real>-0.20999999999999999</real>
 	<key>FRAppliancePreferedOrderValue</key>
-	<integer>-1</integer>
+	<integer>2</integer>
 	<key>FRRemoteAppliance</key>
 	<true/>
 	<key>NSPrincipalClass</key>
-	<string>SapphireAppliance</string>
+	<string>SapphireAppliance</string>	
+  <!-- ATV2 -->
+  <key>FRApplianceCategoryDescriptors</key>
+	<array>
+		<dict>
+			<key>identifier</key>
+			<string>Sapphire</string>
+			<key>is-network-dependent</key>
+			<false/>
+			<key>is-share-dependent</key>
+			<false/>
+			<key>is-store-category</key>
+			<false/>
+			<key>name</key>
+			<string>Sapphire</string>
+			<key>preferred-order</key>
+			<real>1</real>
+			<key>priority</key>
+			<real>6</real>
+		</dict>
+  </array>
 </dict>
 </plist>
Index: SapphireFrappliance/SapphireAppliance.m
===================================================================
--- SapphireFrappliance/SapphireAppliance.m	(Revision 493)
+++ SapphireFrappliance/SapphireAppliance.m	(Arbeitskopie)
@@ -27,6 +27,20 @@
 
 #import <SapphireCompatClasses/BackRowUtils.h>
 
+// BRAppliance protocol
+@interface BRApplianceInfo
++(id)infoForApplianceBundle:(id)bundle;
+-(id)applianceCategoryDescriptors;
+@end
+
+@interface BRApplianceCategory
++(id)categoryWithName:(NSString *)name identifier:(NSString *)identifier preferredOrder:(float)order;
+-(void)setIsStoreCategory:(BOOL)isStoreCategory;
+-(void)setIsDefaultCategory:(BOOL)isDefaultCategory;
+-(void)setShouldDisplayOnStartup:(BOOL)shouldDisplayOnStartup;
+@end
+
+
 @implementation SapphireAppliance
 
 + (void) initialize
@@ -34,77 +48,135 @@
 	NSString *myBundlePath = [[NSBundle bundleForClass:[self class]] bundlePath];
 	NSString *frameworkPath = [myBundlePath stringByAppendingPathComponent:@"Contents/Frameworks"];
 	SapphireLoadFramework(frameworkPath);
-    Class cls = NSClassFromString( @"BRFeatureManager" );
-    if ( cls == Nil )
-        return;
-	
-    [[cls sharedInstance] enableFeatureNamed: [[NSBundle bundleForClass: self] bundleIdentifier]];
+	Class cls = NSClassFromString( @"BRFeatureManager" );
+	if ( cls == Nil )
+		return;
+	[[cls sharedInstance] enableFeatureNamed: [[NSBundle bundleForClass: self] bundleIdentifier]];
 }
 
 + (NSString *) className
 {
-	static BOOL checked = NO;
-    // get around the whitelist
+	// get around the whitelist
+	// this function will get the real class name from the runtime, and
+	// will assuredly not recurse back to here
+	NSString * className = NSStringFromClass( self );
     
-    // this function will get the real class name from the runtime, and
-    // will assuredly not recurse back to here
-    NSString * className = NSStringFromClass( self );
-    
-    // BackRow has its own exception class which provides backtrace
-    // helpers. It returns a parsed trace, with function names. We'll
-    // look for the name of the function which is known to call this
-    // function to check against the whitelist, and if we find it we'll
-    // lie about our name, purely to escape that check.
-    // Also, the backtracer method is a class routine, meaning that we
-    // don't have to even generate an exception - woohoo!
+	// BackRow has its own exception class which provides backtrace
+	// helpers. It returns a parsed trace, with function names. We'll
+	// look for the name of the function which is known to call this
+	// function to check against the whitelist, and if we find it we'll
+	// lie about our name, purely to escape that check.
+	// Also, the backtracer method is a class routine, meaning that we
+	// don't have to even generate an exception - woohoo!
 	NSString *backtrace = [BRBacktracingException backtrace];
-    NSRange range = [backtrace rangeOfString: @"_loadApplianceInfoAtPath:"];
-	if (range.location == NSNotFound && !checked)
+	NSRange range = [backtrace rangeOfString: @"_loadApplianceInfoAtPath:"];
+	if ( range.location != NSNotFound )
 	{
+		// this is the whitelist check -- tell a Great Big Fib
+		className = @"RUIMoviesAppliance";     // could be anything in the whitelist, really
+	}
+	if (range.location == NSNotFound)
+	{
+		//code from ATVFiles. Thx!
 		range = [backtrace rangeOfString: @"(in BackRow)"];
-		checked = YES;
+    if(range.location != NSNotFound) {
+      NSLog(@"+[%@ className] called for Leopard/ATV2 whitelist check, so I'm lying, m'kay?", className);
+      // 10.5/ATV2 (and 1.1, but that's handled above)
+      className = @"RUIDVDAppliance";
+    }
 	}
-    if ( range.location != NSNotFound )
-    {
-        // this is the whitelist check -- tell a Great Big Fib
-        className = @"RUIMoviesAppliance";     // could be anything in the whitelist, really
-    }
-    
-    return ( className );
+	return ( className );
 }
 
+-(NSString *)applianceKey {
+	return @"SapphireAppliance";
+}
+
+-(NSString *)applianceName {
+	return @"SapphireAppliance";
+}
+
 - (NSString *) moduleIconName
 {
-    // replace this with your own icon name
-    return ( @"SapphireIcon.png" );
+	// replace this with your own icon name
+	return ( @"SapphireIcon.png" );
 }
 
 - (NSString *) moduleName
 {
-    // this doesn't appear to be actually *used*, but even so:
-    return ( BRLocalizedString(@"Sapphire", @"Main Menu item name") );
+	// this doesn't appear to be actually *used*, but even so:
+	return ( BRLocalizedString(@"Sapphire", @"Main Menu item name") );
 }
 
 + (NSString *) moduleKey
 {
-    // change this to match your CFBundleIdentifier
-    return ( @"Nanopi.net.UCIJoker.Sapphire" );
+	// change this to match your CFBundleIdentifier
+	return ( @"Nanopi.net.UCIJoker.Sapphire" );
 }
 
 - (NSString *) moduleKey
 {
-    return ( [SapphireAppliance moduleKey] );
+	return ( [SapphireAppliance moduleKey] );
 }
 
-- (BRLayerController *)applianceController
+- (id)applianceController
 {
-    return ( [[[SapphireApplianceController alloc] initWithScene: nil] autorelease] );
+	NSLog(@"in -SapphireApplicance applianceController");
+	return ( [[[SapphireApplianceController alloc] initWithScene: nil] autorelease] );
 }
 
-- (BRLayerController *) applianceControllerWithScene: (BRRenderScene *) scene
+- (id) applianceControllerWithScene: (id) scene
 {
-    // this function is called when your item is selected on the main menu
-    return ( [[[SapphireApplianceController alloc] initWithScene: scene] autorelease] );
+	// this function is called when your item is selected on the main menu
+	return ( [[[SapphireApplianceController alloc] initWithScene: scene] autorelease] );
 }
 
+/**
+ * This implements the BRAppliance protocol from ATV2.
+ */
+-(id)applianceInfo {
+	NSLog(@"in -SapphireApplicance applianceInfo");
+
+	BRApplianceInfo* p = [BRApplianceInfo infoForApplianceBundle:[NSBundle bundleForClass:[self class]]];
+  NSMutableArray *categories = [NSMutableArray array];
+  
+  NSEnumerator *enumerator = [[p applianceCategoryDescriptors] objectEnumerator];
+  id obj;
+  while((obj = [enumerator nextObject]) != nil) {
+    BRApplianceCategory *category = [BRApplianceCategory categoryWithName:[obj valueForKey:@"name"] identifier:[obj valueForKey:@"identifier"] preferredOrder:[[obj valueForKey:@"preferred-order"] floatValue]];
+    [categories addObject:category];
+		NSLog(@"asdsa");
+  }
+  return [BRApplianceInfo infoForApplianceBundle:[NSBundle bundleForClass:[self class]]];
+}
+
+-(id)applianceCategories {
+	NSLog(@"in -SapphireApplicance applianceCategories");
+  NSMutableArray *categories = [NSMutableArray array];
+  
+  NSEnumerator *enumerator = [[[self applianceInfo] applianceCategoryDescriptors] objectEnumerator];
+  id obj;
+  while((obj = [enumerator nextObject]) != nil) {
+    BRApplianceCategory *category = [BRApplianceCategory categoryWithName:[obj valueForKey:@"name"] identifier:[obj valueForKey:@"identifier"] preferredOrder:[[obj valueForKey:@"preferred-order"] floatValue]];
+    [categories addObject:category];
+  }
+  return categories;
+}
+
+-(id)identifierForContentAlias:(id)fp8 {
+  return @"Sapphire";
+}
+
+-(id)controllerForIdentifier:(id)fp8 {
+  return [self applianceController];
+}
+
+-(id)initWithSettings:(id)settings {
+  return [super init];
+}
+
+-(id)version {
+  return @"1.0";
+}
+
 @end
Index: SapphireFrappliance/SapphireAppliance.h
===================================================================
--- SapphireFrappliance/SapphireAppliance.h	(Revision 493)
+++ SapphireFrappliance/SapphireAppliance.h	(Arbeitskopie)
@@ -23,7 +23,28 @@
  *
  * This class bypasses the whitelist check and sets up backrow to load and use the main controller.
  */
-@interface SapphireAppliance : BRAppliance 
-{
+
+@protocol BRAppliance <NSObject>
+- (id)applianceInfo;
+- (id)applianceCategories;
+- (id)identifierForContentAlias:(id)fp8;
+- (id)controllerForIdentifier:(id)fp8;
+@end
+
+// this just makes the warnings shut up
+@interface SapphireAppliance : NSObject <BRAppliance, BRApplianceProtocol> {
+	
 }
+// BRApplianceProtocol protocol
+-(id)applianceController;
+-(id)applianceControllerWithScene:(id)scene;
+-(id)version;
+-(id)initWithSettings:(id)settings;
+
+// BRAppliance protocol
+-(id)applianceInfo;
+-(id)applianceCategories;
+-(id)identifierForContentAlias:(id)fp8;
+-(id)controllerForIdentifier:(id)fp8;
 @end
+

