adium-1.4 3169:6740a3e14bd4: Deloggify

commits at adium.im commits at adium.im
Sat Oct 30 08:19:37 UTC 2010


details:	http://hg.adium.im/adium-1.4/rev/6740a3e14bd4
revision:	3169:6740a3e14bd4
author:		Evan Schoenberg
date:		Sat Oct 30 03:01:17 2010 -0500

Deloggify
Subject: adium-1.4 3170:dd0efc92e5e3: Another site where a freed warning should be issued. There's still some overrelease/underetain issue out there, per reports, but I can't reproduce it... It'll be 1.4.1 fodder.

details:	http://hg.adium.im/adium-1.4/rev/dd0efc92e5e3
revision:	3170:dd0efc92e5e3
author:		Evan Schoenberg
date:		Sat Oct 30 03:02:56 2010 -0500

Another site where a freed warning should be issued. There's still some overrelease/underetain issue out there, per reports, but I can't reproduce it... It'll be 1.4.1 fodder.
Subject: adium-1.4 3171:a8df3d4b8dd0: Fixed AIContactMenu to populate its NSMenuItems lazily rather than at initialization. Importantly, this means we no longer immediately load the buddy icon of every contact on the contact list regardless of whether it is visible or not.

details:	http://hg.adium.im/adium-1.4/rev/a8df3d4b8dd0
revision:	3171:a8df3d4b8dd0
author:		Evan Schoenberg
date:		Sat Oct 30 03:18:31 2010 -0500

Fixed AIContactMenu to populate its NSMenuItems lazily rather than at initialization. Importantly, this means we no longer immediately load the buddy icon of every contact on the contact list regardless of whether it is visible or not.
Subject: adium-1.4 3172:25b5814b1ae3: Remove some debug logging

details:	http://hg.adium.im/adium-1.4/rev/25b5814b1ae3
revision:	3172:25b5814b1ae3
author:		Evan Schoenberg
date:		Sat Oct 30 03:19:23 2010 -0500

Remove some debug logging

diffs (472 lines):

diff -r 9fcc0b9d4889 -r 25b5814b1ae3 Frameworks/AIUtilities Framework/Source/AIOutlineViewAdditions.m
--- a/Frameworks/AIUtilities Framework/Source/AIOutlineViewAdditions.m	Sat Oct 30 02:03:05 2010 -0500
+++ b/Frameworks/AIUtilities Framework/Source/AIOutlineViewAdditions.m	Sat Oct 30 03:19:23 2010 -0500
@@ -24,16 +24,12 @@
 //Redisplay an item (passing nil is the same as requesting a redisplay of the entire list)
 - (void)redisplayItem:(id)item
 {
-	static int redisplayNumber = 0;
-
 	if (item) {
 		int row = [self rowForItem:item];
 		if (row >= 0 && row < [self numberOfRows]) {
-			NSLog(@"Redisplay #%i  %@", ++redisplayNumber, item);
 			[self setNeedsDisplayInRect:[self rectOfRow:row]];
 		}
 	} else {
-		NSLog(@"Redisplay #%i  %@", ++redisplayNumber, item);
 		[self setNeedsDisplay:YES];
 	}
 }
diff -r 9fcc0b9d4889 -r 25b5814b1ae3 Frameworks/Adium Framework/Source/AIAbstractListController.m
--- a/Frameworks/Adium Framework/Source/AIAbstractListController.m	Sat Oct 30 02:03:05 2010 -0500
+++ b/Frameworks/Adium Framework/Source/AIAbstractListController.m	Sat Oct 30 03:19:23 2010 -0500
@@ -674,6 +674,11 @@
 
 - (BOOL)outlineView:(NSOutlineView *)outlineView isGroup:(AIProxyListObject *)item
 {
+#ifdef DEBUG_BUILD
+	if (NSIsFreedObject(item)) {
+		NSLog(@"Attempting to use a freed listobject proxy in %@", NSStringFromSelector(_cmd));
+	}
+#endif
 	return (!item || ([item.listObject isKindOfClass:[AIListGroup class]]));
 }
 
diff -r 9fcc0b9d4889 -r 25b5814b1ae3 Frameworks/Adium Framework/Source/AIAbstractListObjectMenu.m
--- a/Frameworks/Adium Framework/Source/AIAbstractListObjectMenu.m	Sat Oct 30 02:03:05 2010 -0500
+++ b/Frameworks/Adium Framework/Source/AIAbstractListObjectMenu.m	Sat Oct 30 03:19:23 2010 -0500
@@ -71,7 +71,8 @@
 {
 	if(!menu) {
 		menu = [[NSMenu allocWithZone:[NSMenu zone]] init];
-		
+		[menu setDelegate:self];
+
 		[menu setMenuChangedMessagesEnabled:NO];
 		for (NSMenuItem *menuItem in self.menuItems)
 			[menu addItem:menuItem];
diff -r 9fcc0b9d4889 -r 25b5814b1ae3 Frameworks/Adium Framework/Source/AIContactMenu.h
--- a/Frameworks/Adium Framework/Source/AIContactMenu.h	Sat Oct 30 02:03:05 2010 -0500
+++ b/Frameworks/Adium Framework/Source/AIContactMenu.h	Sat Oct 30 03:19:23 2010 -0500
@@ -24,6 +24,7 @@
 	BOOL					shouldDisplayGroupHeaders;
 	BOOL					shouldUseUserIcon;
 	BOOL					shouldSetTooltip;
+	BOOL					shouldIncludeContactListMenuItem;
 }
 
 + (id)contactMenuWithDelegate:(id<AIContactMenuDelegate>)inDelegate forContactsInObject:(AIListObject *)inContainingObject;
@@ -34,13 +35,15 @@
 @end
 
 @protocol AIContactMenuDelegate <NSObject>
-- (void)contactMenu:(AIContactMenu *)inContactMenu didRebuildMenuItems:(NSArray *)menuItems;
+- (void)contactMenuDidRebuild:(AIContactMenu *)inContactMenu;
 @optional
 - (void)contactMenu:(AIContactMenu *)inContactMenu didSelectContact:(AIListContact *)inContact; 
 - (AIListContact *)contactMenu:(AIContactMenu *)inContactMenu validateContact:(AIListContact *)inContact; 
 - (BOOL)contactMenu:(AIContactMenu *)inContactMenu shouldIncludeContact:(AIListContact *)inContact; 
 - (BOOL)contactMenuShouldUseUserIcon:(AIContactMenu *)inContactMenu; 
 - (BOOL)contactMenuShouldSetTooltip:(AIContactMenu *)inContactMenu; 
+- (BOOL)contactMenuShouldIncludeContactListMenuItem:(AIContactMenu *)inContactMenu; 
+
 // Called on each rebuild:
 - (BOOL)contactMenuShouldDisplayGroupHeaders:(AIContactMenu *)inContactMenu; //only applies to contained groups
 - (BOOL)contactMenuShouldUseDisplayName:(AIContactMenu *)inContactMenu; 
diff -r 9fcc0b9d4889 -r 25b5814b1ae3 Frameworks/Adium Framework/Source/AIContactMenu.m
--- a/Frameworks/Adium Framework/Source/AIContactMenu.m	Sat Oct 30 02:03:05 2010 -0500
+++ b/Frameworks/Adium Framework/Source/AIContactMenu.m	Sat Oct 30 03:19:23 2010 -0500
@@ -14,10 +14,11 @@
 #import <Adium/AIListContact.h>
 #import <Adium/AIListGroup.h>
 #import <Adium/AIContactList.h>
+#import <AIUtilities/AIStringAdditions.h>
 
 @interface AIContactMenu ()
 - (id)initWithDelegate:(id<AIContactMenuDelegate>)inDelegate forContactsInObject:(AIListObject *)inContainingObject;
-- (NSArray *)contactMenusForListObjects:(NSArray *)listObjects;
+- (NSMutableArray *)contactMenusForListObjects:(NSArray *)listObjects;
 - (NSArray *)listObjectsForMenuFromArrayOfListObjects:(NSArray *)listObjects;
 - (void)_updateMenuItem:(NSMenuItem *)menuItem;
 @end
@@ -114,7 +115,7 @@
 	delegate = inDelegate;
 	
 	//Ensure the the delegate implements all required selectors and remember which optional selectors it supports.
-	if (delegate) NSParameterAssert([delegate respondsToSelector:@selector(contactMenu:didRebuildMenuItems:)]);
+	if (delegate) NSParameterAssert([delegate respondsToSelector:@selector(contactMenuDidRebuild:)]);
 	delegateRespondsToDidSelectContact = [delegate respondsToSelector:@selector(contactMenu:didSelectContact:)];
 	delegateRespondsToShouldIncludeContact = [delegate respondsToSelector:@selector(contactMenu:shouldIncludeContact:)];
 	delegateRespondsToValidateContact = [delegate respondsToSelector:@selector(contactMenu:validateContact:)];
@@ -130,6 +131,10 @@
 	
 	shouldSetTooltip = ([delegate respondsToSelector:@selector(contactMenuShouldSetTooltip:)] &&
 								 [delegate contactMenuShouldSetTooltip:self]);	
+	
+	shouldIncludeContactListMenuItem = ([delegate respondsToSelector:@selector(contactMenuShouldIncludeContactListMenuItem:)] &&
+										  [delegate contactMenuShouldIncludeContactListMenuItem:self]);	
+	
 }
 - (id<AIContactMenuDelegate>	)delegate
 {
@@ -150,7 +155,7 @@
 	shouldDisplayGroupHeaders = ([delegate respondsToSelector:@selector(contactMenuShouldDisplayGroupHeaders:)] &&
 								 [delegate contactMenuShouldDisplayGroupHeaders:self]);
 	
-	[delegate contactMenu:self didRebuildMenuItems:[self menuItems]];
+	[delegate contactMenuDidRebuild:self];
 }
 
 /*!
@@ -196,7 +201,23 @@
 	}
 	
 	// Create menus for them
-	return [self contactMenusForListObjects:listObjects];
+	NSMutableArray *contactMenus = [self contactMenusForListObjects:listObjects];
+	
+	if (shouldIncludeContactListMenuItem) {
+		BOOL needsSeparator = (contactMenus.count > 0);
+			
+		NSMenuItem	*aMenuItem = [[[NSMenuItem alloc] initWithTitle:[AILocalizedString(@"Contact List", nil) stringByAppendingEllipsis]
+															 action:@selector(toggleContactList:)
+													  keyEquivalent:@""] autorelease];
+		[aMenuItem setTarget:adium.interfaceController];
+		[contactMenus insertObject:aMenuItem atIndex:0];
+		 
+		if (needsSeparator) {
+			[contactMenus insertObject:[NSMenuItem separatorItem] atIndex:1];
+		}
+	}
+	
+	return contactMenus;
 }
 
 /*!
@@ -229,7 +250,7 @@
 /*!
 * @brief Creates an array of NSMenuItems for each AIListObject
  */
-- (NSArray *)contactMenusForListObjects:(NSArray *)listObjects
+- (NSMutableArray *)contactMenusForListObjects:(NSArray *)listObjects
 {
 	NSMutableArray	*menuItemArray = [NSMutableArray array];
 	
@@ -249,13 +270,15 @@
 
 				// The group isn't clickable.
 				[menuItem setEnabled:NO];
-				[self _updateMenuItem:menuItem];
 				
 				// Add the group and contained objects to the array.
 				[menuItemArray addObject:menuItem];
 				[menuItemArray addObjectsFromArray:[self contactMenusForListObjects:containedListObjects]];
 				
 				[menuItem release];
+				
+				/* Note that we'll call _updateMenuItem before the item is actually displayed, to set
+				 * the title, image, etc. */
 			}
 		} else {
 			// Just add the menu item.
@@ -264,9 +287,11 @@
 																						action:@selector(selectContactMenuItem:)
 																				 keyEquivalent:@""
 																			 representedObject:listObject];
-			[self _updateMenuItem:menuItem];
 			[menuItemArray addObject:menuItem];
 			[menuItem release];
+			
+			/* Note that we'll call _updateMenuItem before the item is actually displayed, to set
+			 * the title, image, etc. */
 		}
 
 	}
@@ -303,6 +328,30 @@
 	}
 }
 
+- (NSInteger)numberOfItemsInMenu:(NSMenu *)inMenu
+{
+	/* We manage the number of items in the menu as it changes, live (mostly because of laziness - it's already
+	 * implemented as of this optimization to use menu:updateItem:atIndex:shouldCancel: and works just fine.
+	 */
+	return inMenu.numberOfItems;
+}
+	 
+- (BOOL)menu:(NSMenu *)inMenu updateItem:(NSMenuItem *)menuItem atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel
+{
+	if (shouldCancel)
+		return NO;
+
+	[self _updateMenuItem:menuItem];
+	
+	//Validate the menu items as they are added since they weren't previously validated when the menu was clicked
+	//XXX Is this needed? Maintained from CBStatusMenuItemController. Won't hurt.
+	if ([menuItem.target respondsToSelector:@selector(validateMenuItem:)]) {
+		[menuItem.target validateMenuItem:menuItem];
+	}
+	
+	return YES;
+}
+
 /*!
  * @brief Update menu when a contact's status changes
  */
@@ -335,11 +384,7 @@
 					} else {
 						[self rebuildMenu];
 					}
-				} else { 
-					[self _updateMenuItem:menuItem];
 				}
-			} else {
-				[self _updateMenuItem:menuItem];
 			}
 		}
 	}
diff -r 9fcc0b9d4889 -r 25b5814b1ae3 Frameworks/Adium Framework/Source/AIListOutlineView+Drawing.m
--- a/Frameworks/Adium Framework/Source/AIListOutlineView+Drawing.m	Sat Oct 30 02:03:05 2010 -0500
+++ b/Frameworks/Adium Framework/Source/AIListOutlineView+Drawing.m	Sat Oct 30 03:19:23 2010 -0500
@@ -269,8 +269,7 @@
 - (void)drawRect:(NSRect)rect
 {	
 	static int timesDrawn = 0;
-	NSLog(@"-[AIListOUtlineView drawRect:] Drew %i times", ++timesDrawn);
-	
+
 	[super drawRect:rect];
 	
 	/*	#################### Crappy Code ###################
diff -r 9fcc0b9d4889 -r 25b5814b1ae3 Plugins/Dual Window Interface/AIAccountSelectionView.m
--- a/Plugins/Dual Window Interface/AIAccountSelectionView.m	Sat Oct 30 02:03:05 2010 -0500
+++ b/Plugins/Dual Window Interface/AIAccountSelectionView.m	Sat Oct 30 03:19:23 2010 -0500
@@ -392,7 +392,7 @@
 /*!
  * @brief Contact menu delegate
  */
-- (void)contactMenu:(AIContactMenu *)inContactMenu didRebuildMenuItems:(NSArray *)menuItems {
+- (void)contactMenuDidRebuild:(AIContactMenu *)inContactMenu {
 	AILogWithSignature(@"");
 	[popUp_contacts setMenu:[inContactMenu menu]];
 	[self chatDestinationChanged:nil];
diff -r 9fcc0b9d4889 -r 25b5814b1ae3 Plugins/Invite to Chat Plugin/DCInviteToChatWindowController.m
--- a/Plugins/Invite to Chat Plugin/DCInviteToChatWindowController.m	Sat Oct 30 02:03:05 2010 -0500
+++ b/Plugins/Invite to Chat Plugin/DCInviteToChatWindowController.m	Sat Oct 30 03:19:23 2010 -0500
@@ -167,7 +167,7 @@
 /*!
  * @brief Contact menu delegate
  */
-- (void)contactMenu:(AIContactMenu *)inContactMenu didRebuildMenuItems:(NSArray *)menuItems {
+- (void)contactMenuDidRebuild:(AIContactMenu *)inContactMenu {
 	[menu_contacts setMenu:[inContactMenu menu]];
 }
 
diff -r 9fcc0b9d4889 -r 25b5814b1ae3 Plugins/Send Message Contact Alert/ESSendMessageAlertDetailPane.m
--- a/Plugins/Send Message Contact Alert/ESSendMessageAlertDetailPane.m	Sat Oct 30 02:03:05 2010 -0500
+++ b/Plugins/Send Message Contact Alert/ESSendMessageAlertDetailPane.m	Sat Oct 30 03:19:23 2010 -0500
@@ -167,7 +167,7 @@
 	[self detailsForHeaderChanged];
 }
 
-- (void)contactMenu:(AIContactMenu *)inContactMenu didRebuildMenuItems:(NSArray *)menuItems
+- (void)contactMenuDidRebuild:(AIContactMenu *)inContactMenu 
 {
 	NSMenu *tempMenu = [inContactMenu menu];
 	[tempMenu addItemWithTitle:@"" action:nil keyEquivalent:@""];
diff -r 9fcc0b9d4889 -r 25b5814b1ae3 Plugins/Status Menu Item/CBStatusMenuItemController.h
--- a/Plugins/Status Menu Item/CBStatusMenuItemController.h	Sat Oct 30 02:03:05 2010 -0500
+++ b/Plugins/Status Menu Item/CBStatusMenuItemController.h	Sat Oct 30 03:19:23 2010 -0500
@@ -36,9 +36,10 @@
 	
 	NSMenu                  *mainMenu;
 	NSMenu					*mainAccountsMenu;
-	NSMenu					*mainContactsMenu;
 	NSMenu					*mainOptionsMenu;
 
+	NSMenuItem				*contactsMenuItem;
+	
 	AIContactMenu			*contactMenu;
 	AIAccountMenu           *accountMenu;
 	AIStatusMenu			*statusMenu;
@@ -46,7 +47,7 @@
 
 	NSMutableArray          *accountMenuItemsArray;
 	NSMutableArray          *stateMenuItemsArray;
-	NSMutableArray			*contactMenuItemsArray;
+	NSInteger				currentContactMenuItemsCount;
 	NSMutableArray          *openChatsArray;
 
 	NSTimer					*unviewedContentFlash;
diff -r 9fcc0b9d4889 -r 25b5814b1ae3 Plugins/Status Menu Item/CBStatusMenuItemController.m
--- a/Plugins/Status Menu Item/CBStatusMenuItemController.m	Sat Oct 30 02:03:05 2010 -0500
+++ b/Plugins/Status Menu Item/CBStatusMenuItemController.m	Sat Oct 30 03:19:23 2010 -0500
@@ -49,10 +49,14 @@
 - (void)updateUnreadCount;
 - (void)updateOpenChats;
 - (void)updateStatusItemLength;
+
+ at property (nonatomic, retain) NSMenuItem *contactsMenuItem;
 @end
 
 @implementation CBStatusMenuItemController
 
+ at synthesize contactsMenuItem;
+
 + (CBStatusMenuItemController *)statusMenuItemController
 {
 	return [[[self alloc] init] autorelease];
@@ -75,9 +79,6 @@
 		mainMenu = [[NSMenu alloc] init];
 		[mainMenu setDelegate:self];
 
-		mainContactsMenu = [[NSMenu alloc] init];
-		[mainContactsMenu setDelegate:self];
-
 		mainAccountsMenu = [[NSMenu alloc] init];
 		[mainAccountsMenu setDelegate:self];
 		
@@ -86,13 +87,11 @@
 
 		// Set the main menu as the status item's menu
 		statusItemView.menu = mainMenu;
-		statusItemView.alternateMenu = mainContactsMenu;
 		
 		// Create the caches for our menu items
 		accountMenuItemsArray = [[NSMutableArray alloc] init];
 		stateMenuItemsArray = [[NSMutableArray alloc] init];
 		openChatsArray = [[NSMutableArray alloc] init];
-		contactMenuItemsArray = [[NSMutableArray alloc] init];
 
 		// Flag all the menus as needing updates
 		mainMenuNeedsUpdate = YES;
@@ -100,6 +99,11 @@
 		accountsMenuNeedsUpdate = YES;
 		optionsMenuNeedsUpdate = YES;
 		
+		self.contactsMenuItem = [[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:AILocalizedString(@"Contacts",nil)
+																					 target:self
+																					 action:nil
+																			  keyEquivalent:@""];
+
 		NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
 		//Register to recieve chat opened and chat closed notifications
 		[notificationCenter addObserver:self
@@ -185,11 +189,9 @@
 	[accountMenuItemsArray release];
 	[stateMenuItemsArray release];
 	[openChatsArray release];
-	[contactMenuItemsArray release];
 	
 	// The menus
 	[mainMenu release];
-	[mainContactsMenu release];
 	[mainAccountsMenu release];
 	[mainOptionsMenu release];
 	
@@ -513,17 +515,22 @@
 /*!
  * @brief AIContactMenu delegate method
  */
-- (void)contactMenu:(AIContactMenu *)inContactMenu didRebuildMenuItems:(NSArray *)menuItems
+- (void)contactMenuDidRebuild:(AIContactMenu *)inContactMenu 
 {
+	NSMenu *menu = inContactMenu.menu;
+
+	NSInteger newNumberOfMenuItems = menu.numberOfItems;
+
 	// Going from or to 0 contacts requires a main menu update
-	if ([contactMenuItemsArray count] == 0 || [menuItems count] == 0)
+	if (currentContactMenuItemsCount == 0 || newNumberOfMenuItems == 0)
 		mainMenuNeedsUpdate = YES;
 
-	[contactMenuItemsArray release];
-	contactMenuItemsArray = [menuItems retain];
+	currentContactMenuItemsCount = 	menu.numberOfItems;
 	
-	// Update the next time we're clicked.
-	contactsMenuNeedsUpdate = YES;
+	/* The alternate menu is what shows if you option-click the menu item */
+	statusItemView.alternateMenu = menu;
+	
+	[self.contactsMenuItem setSubmenu:menu];
 }
 
 /*!
@@ -586,6 +593,11 @@
 	return YES;
 }
 
+- (BOOL) contactMenuShouldIncludeContactListMenuItem:(AIContactMenu *)inContactMenu
+{
+	return YES;
+}
+
 #pragma mark List Object Observer
 /*!
  * @brief List Observer delegate method
@@ -689,16 +701,11 @@
 		[menu removeAllItems];
 		
 		// Show the contacts menu if we have any contacts to display
-		if ([contactMenuItemsArray count] > 0) {
+		if ([contactMenu.menu numberOfItems] > 0) {
 			// Add contacts
-			menuItem = [[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:AILocalizedString(@"Contacts",nil)
-																			target:self
-																			action:nil
-																	 keyEquivalent:@""];
-			
-			[menuItem setSubmenu:mainContactsMenu];
-			[menu addItem:menuItem];
+			[menu addItem:self.contactsMenuItem];
 			[menuItem release];
+
 		} else {
 			[menu addItemWithTitle:[AILocalizedString(@"Contact List", nil) stringByAppendingEllipsis]
 							target:adium.interfaceController
@@ -774,31 +781,6 @@
 		
 		//Only update next time if we need to
 		mainMenuNeedsUpdate = NO;
-	// Contacts menu
-	} else if (menu == mainContactsMenu && contactsMenuNeedsUpdate) {
-		NSMenuItem      *menuItem;
-		
-		// Remove previous menu items.
-		[menu removeAllItems];
-		
-		contactsMenuNeedsUpdate = NO;
-	
-		[menu addItemWithTitle:[AILocalizedString(@"Contact List", nil) stringByAppendingEllipsis]
-						target:adium.interfaceController
-						action:@selector(toggleContactList:)
-				 keyEquivalent:@""];
-		
-		if ([contactMenuItemsArray count] > 0)
-			[menu addItem:[NSMenuItem separatorItem]];
-		
-		for (menuItem in contactMenuItemsArray) {
-			[menu addItem:menuItem];
-			
-			//Validate the menu items as they are added since they weren't previously validated when the menu was clicked
-			if ([[menuItem target] respondsToSelector:@selector(validateMenuItem:)]) {
-				[[menuItem target] validateMenuItem:menuItem];
-			}
-		}
 	// Accounts menu
 	} else if (menu == mainAccountsMenu && accountsMenuNeedsUpdate) {
 		NSMenuItem      *menuItem;
diff -r 9fcc0b9d4889 -r 25b5814b1ae3 Source/AIAdvancedInspectorPane.m
--- a/Source/AIAdvancedInspectorPane.m	Sat Oct 30 02:03:05 2010 -0500
+++ b/Source/AIAdvancedInspectorPane.m	Sat Oct 30 03:19:23 2010 -0500
@@ -208,7 +208,7 @@
 													  nil)];
 }
 
-- (void)contactMenu:(AIContactMenu *)inContactMenu didRebuildMenuItems:(NSArray *)menuItems
+- (void)contactMenuDidRebuild:(AIContactMenu *)inContactMenu
 {
 	[popUp_contact setMenu:inContactMenu.menu];
 	




More information about the commits mailing list