diff --git a/Frameworks/Adium Framework/Source/ESObjectWithProperties.m b/Frameworks/Adium Framework/Source/ESObjectWithProperties.m
--- a/Frameworks/Adium Framework/Source/ESObjectWithProperties.m	
+++ b/Frameworks/Adium Framework/Source/ESObjectWithProperties.m	
@@ -18,6 +18,8 @@
 #import <AIUtilities/AIMutableOwnerArray.h>
 #import <Adium/AIProxyListObject.h>
 
+#import <objc/runtime.h>
+
 @interface ESObjectWithProperties (AIPrivate)
 - (void)_applyDelayedProperties:(NSDictionary *)infoDict;
 @end
@@ -42,7 +44,6 @@
 - (id)init
 {
 	if ((self = [super init])) {
-		propertiesDictionary = [[NSMutableDictionary alloc] init];
 		displayDictionary = [[NSMutableDictionary alloc] init];
 	}
 
@@ -84,12 +85,66 @@
         return;
 
     [self willChangeValueForKey:key];
-    
-    if (value) {
-        [propertiesDictionary setObject:value forKey:key];
-    } else {
-        [propertiesDictionary removeObjectForKey:key];
-    }
+    	
+	Ivar ivar = class_getInstanceVariable([self class], [key UTF8String]);
+	
+	if (ivar == NULL) {
+		
+		if (!propertiesDictionary) {
+			// only allocate the dictionary when we're going to actually use it
+			AILogWithSignature(@"Created dictionary for key %@ of %@", key, self);
+			propertiesDictionary = [[NSMutableDictionary alloc] init];
+		}
+		
+		if (value) {
+			AILogWithSignature(@"Add key %@ to %@ (likely class: %@)", key, self, [value class]);
+			[propertiesDictionary setObject:value forKey:key];
+		} else {
+			[propertiesDictionary removeObjectForKey:key];
+		}
+		
+	} else {
+		const char *ivarType = ivar_getTypeEncoding(ivar);
+		
+		if (ivarType[0] == '@') {
+			[oldValue release];
+			[value retain];
+			object_setIvar(self, ivar, value);
+		} else if (strcmp(ivarType, @encode(BOOL)) == 0) {
+			
+			BOOL bValue;
+			
+			if (value)
+				bValue = [value boolValue];
+			else {
+				bValue = FALSE;
+			}
+
+			object_setIvar(self, ivar, (void *)bValue);
+		} else if (strcmp(ivarType, @encode(NSInteger)) == 0) {
+			
+			NSInteger iValue;
+			
+			if (value)
+				iValue = [value integerValue];
+			else {
+				iValue = 0;
+			}
+			
+			object_setIvar(self, ivar, (void *)iValue);
+		} else if (strcmp(ivarType, @encode(int)) == 0) {
+			
+			int iValue;
+			
+			if (value)
+				iValue = [value intValue];
+			else {
+				iValue = 0;
+			}
+			
+			object_setIvar(self, ivar, (void *)iValue);
+		}
+	}
     
     [self object:self didChangeValueForProperty:key notify:notify];
     [self didChangeValueForKey:key];
@@ -161,7 +216,37 @@
  */
 - (id)valueForProperty:(NSString *)key
 {
-    return [propertiesDictionary objectForKey:key];
+	id ret = nil;
+	void *value = 0;
+	
+	Ivar ivar = object_getInstanceVariable(self, [key UTF8String], value);
+	
+	if (ivar == NULL) {
+		
+		// no dictionary -> this property is certainly nil
+		if (propertiesDictionary) {
+			ret = [propertiesDictionary objectForKey:key];
+		}
+		
+	} else {
+		
+		const char *ivarType = ivar_getTypeEncoding(ivar);
+		
+		// attempt to wrap it, if we know how
+		if (strcmp(ivarType, @encode(BOOL)) == 0) {
+			ret = [[NSNumber numberWithBool:(BOOL)value] autorelease];
+		} else if (strcmp(ivarType, @encode(NSInteger)) == 0) {
+			ret = [[NSNumber numberWithInteger:(NSInteger)value] autorelease];
+		} else if (strcmp(ivarType, @encode(int)) == 0) {
+			ret = [[NSNumber numberWithInt:(int)value] autorelease];
+		} else if (ivarType[0] != '@') {
+			AILogWithSignature(@" *** This ivar is not an object but an %s! Should not use -valueForProperty:@\"%@\" ***", ivarType, key);
+		} else {
+			ret = (id)value;
+		}
+	}
+	
+    return ret;
 }
 
 /*!
@@ -171,20 +256,71 @@
  */
 - (NSInteger)integerValueForProperty:(NSString *)key
 {
-	NSNumber *number = [self numberValueForProperty:key];
-	return number ? [number integerValue] : 0;
+	NSInteger ret = 0;
+	
+	Ivar ivar = class_getInstanceVariable([self class], [key UTF8String]);
+	
+	if (ivar == NULL) {
+		NSNumber *number = [self numberValueForProperty:key];
+		ret = number ? [number integerValue] : NO;
+	} else {
+		
+		const char *ivarType = ivar_getTypeEncoding(ivar);
+		
+		if (strcmp(ivarType, @encode(NSInteger)) != 0) {
+			AILogWithSignature(@"%@'s %@ ivar is not an NSInteger but an %s! Will attempt to cast, but should not use -integerValueForProperty: @\"%@\"", self, key, ivarType, key);
+		}
+		
+		ret = (NSInteger)object_getIvar(self, ivar);
+	}
+	
+    return ret;
 }
 
 - (int)intValueForProperty:(NSString *)key
 {
-	NSNumber *number = [self numberValueForProperty:key];
-	return number ? [number intValue] : 0;
+	int ret = 0;
+	
+	Ivar ivar = class_getInstanceVariable([self class], [key UTF8String]);
+	
+	if (ivar == NULL) {
+		NSNumber *number = [self numberValueForProperty:key];
+		ret = number ? [number intValue] : NO;
+	} else {
+		
+		const char *ivarType = ivar_getTypeEncoding(ivar);
+		
+		if (strcmp(ivarType, @encode(int)) != 0) {
+			AILogWithSignature(@"%@'s %@ ivar is not an int but an %s! Will attempt to cast, but should not use -intValueForProperty: @\"%@\"", self, key, ivarType, key);
+		}
+		
+		ret = (int)object_getIvar(self, ivar);
+	}
+	
+    return ret;
 }
 
 - (BOOL)boolValueForProperty:(NSString *)key
 {
-	NSNumber *number = [self numberValueForProperty:key];
-	return number ? [number boolValue] : NO;
+	BOOL ret = FALSE;
+	
+	Ivar ivar = class_getInstanceVariable([self class], [key UTF8String]);
+	
+	if (ivar == NULL) {
+		NSNumber *number = [self numberValueForProperty:key];
+		ret = number ? [number boolValue] : NO;
+	} else {
+		
+		const char *ivarType = ivar_getTypeEncoding(ivar);
+		
+		if (strcmp(ivarType, @encode(BOOL)) != 0) {
+			AILogWithSignature(@"%@'s %@ ivar is not an BOOL but an %s! Will attempt to cast, but should not use -boolValueForProperty: @\"%@\"", self, key, ivarType, key);
+		}
+		
+		ret = (BOOL)object_getIvar(self, ivar);
+	}
+	
+    return ret;
 }
 
 /*!
