Index: src/apps/mail/Mail.h
===================================================================
--- src/apps/mail/Mail.h	(revision 22007)
+++ src/apps/mail/Mail.h	(working copy)
@@ -92,6 +92,7 @@
 	M_SIZE,
 	M_BEGINNER,
 	M_EXPERT,
+
 	/* file */
 	M_REPLY,
 	M_REPLY_TO_SENDER,
@@ -117,6 +118,7 @@
 	M_STATUS,
 	M_OPEN_MAIL_BOX,
 	M_OPEN_MAIL_FOLDER,
+
 	/* edit */
 	M_SELECT,
 	M_QUOTE,
@@ -127,15 +129,22 @@
 	M_SIG_MENU,
 	M_FIND,
 	M_FIND_AGAIN,
+
+	/* queries */
+	M_EDIT_QUERIES,
+	M_EXECUTE_QUERY,
+
 	/* encls */
 	M_ADD,
 	M_REMOVE,
 	M_OPEN,
 	M_COPY,
+
 	/* nav */
 	M_NEXTMSG,
 	M_PREVMSG,
 	M_SAVE_POSITION,
+
 	/* Spam GUI button and menu items.  Order is important. */
 	M_SPAM_BUTTON,
 	M_TRAIN_SPAM_AND_DELETE,
@@ -261,6 +270,8 @@
 		status_t TrainMessageAs (const char *CommandWord);
 
 	private:
+		const char * _BuildQueryString(BEntry *entry);		
+
 		BEmailMessage	*fMail;
 		entry_ref *fRef;			// Reference to currently displayed file
 		int32 fFieldState;
Index: src/apps/mail/Mail.cpp
===================================================================
--- src/apps/mail/Mail.cpp	(revision 22007)
+++ src/apps/mail/Mail.cpp	(working copy)
@@ -119,13 +119,24 @@
 static const char *kMailFolder = "mail";
 static const char *kMailboxFolder = "mail/mailbox";
 
+static const char *kQueriesDirectory = "mail/queries";
+static const char *kQuerySignature = "application/x-vnd.Be-query"; // B_QUERY_MIMETYPE
+static const char *kAttrQueryInitialMode = "_trk/qryinitmode"; // taken from src/kits/tracker/Attributes.h
+static const char *kAttrQueryInitialString = "_trk/qryinitstr";
+static const char *kAttrQueryInitialNumAttrs = "_trk/qryinitnumattrs";
+static const char *kAttrQueryInitialAttrs = "_trk/qryinitattrs";
+static const char *kAttrQueryInitialMime = "_trk/qryinitmime";
+static const uint32 kAttributeItemMain = 'Fatr'; // taken from src/kits/tracker/FindPanel.h
+static const uint32 kByNameItem = 'Fbyn'; // taken from src/kits/tracker/FindPanel.h
+static const uint32 kByAttributeItem = 'Fbya'; // taken from src/kits/tracker/FindPanel.h
+static const uint32 kByForumlaItem = 'Fbyq'; // taken from src/kits/tracker/FindPanel.h
+
 static const char *kDictDirectory = "word_dictionary";
 static const char *kIndexDirectory = "word_index";
 static const char *kWordsPath = "/boot/optional/goodies/words";
 static const char *kExact = ".exact";
 static const char *kMetaphone = ".metaphone";
 
-
 // Text for both the main menu and the pop-up menu.
 static const char *kSpamMenuItemTextArray[] = {
 	"Mark as Spam and Move to Trash",		// M_TRAIN_SPAM_AND_DELETE
@@ -1227,7 +1238,39 @@
 
 //	#pragma mark -
 
+/*
+// Copied from src/kits/tracker/FindPanel.cpp.
+uint32 
+TMailWindow::InitialMode(const BNode *node)
+{
+	if (!node || node->InitCheck() != B_OK)
+		return kByNameItem;
+	
+	uint32 result;
+	if (node->ReadAttr(kAttrQueryInitialMode, B_INT32_TYPE, 0,
+		(int32 *)&result, sizeof(int32)) <= 0)
+		return kByNameItem;
 
+	return result;
+}
+
+
+// Copied from src/kits/tracker/FindPanel.cpp.
+int32 
+TMailWindow::InitialAttrCount(const BNode *node)
+{
+	if (!node || node->InitCheck() != B_OK)
+		return 1;
+	
+	int32 result;
+	if (node->ReadAttr(kAttrQueryInitialNumAttrs, B_INT32_TYPE, 0,
+		&result, sizeof(int32)) <= 0)
+		return 1;
+	
+	return result;
+}*/
+
+
 TMailWindow::TMailWindow(BRect rect, const char *title, const entry_ref *ref,
 		const char *to, const BFont *font, bool resending, BMessenger *messenger)
 	: BWindow(rect, title, B_DOCUMENT_WINDOW, 0),
@@ -1444,8 +1487,9 @@
 	item->SetTarget(be_app);
 	menu_bar->AddItem(menu);
 	
+	//
 	// View Menu
-	
+	//
 	if (!resending && fIncoming) {
 		menu = new BMenu("View");
 		menu->AddItem(fHeader = new BMenuItem(MDR_DIALECT_CHOICE ("Show Header","H) ヘッダーを表示"),	new BMessage(M_HEADER), 'H'));
@@ -1561,6 +1605,44 @@
 		menu_bar->AddItem(menu);
 	}
 	
+	//
+	// Queries Menu
+	//
+	menu = new BMenu(MDR_DIALECT_CHOICE("Queries","???"));
+	menu->AddItem(new BMenuItem(MDR_DIALECT_CHOICE("Edit Queries...","???..."), new BMessage(M_EDIT_QUERIES), 'E', B_SHIFT_KEY));
+	menu->AddSeparatorItem();
+	menu_bar->AddItem(menu);
+
+	BPath queryPath;
+	// Get the user home directory
+	if (find_directory(B_USER_DIRECTORY, &queryPath) == B_OK) {
+		queryPath.Append(kQueriesDirectory);
+	}
+	
+	BDirectory queryDir(queryPath.Path());
+
+	//	If we find the named query, add it to the menu.
+	BEntry entry;
+	while (queryDir.GetNextEntry(&entry) == B_OK) {
+
+		char name[B_FILE_NAME_LENGTH + 1];
+		entry.GetName(name);
+		
+		const char * queryString = _BuildQueryString(&entry);
+		if (queryString == NULL)
+			continue;
+		
+		QueryMenu *queryMenu = new QueryMenu(name, false);
+		queryMenu->SetTargetForItems(be_app);
+		queryMenu->SetPredicate(queryString);
+		menu->AddItem(queryMenu);
+		
+		delete queryString;
+	}
+
+	//
+	// Menu Bar
+	//
 	Lock();
 	AddChild(menu_bar);
 	height = menu_bar->Bounds().bottom + 1;
@@ -1668,7 +1750,107 @@
 		SetTitleForMessage();
 }
 
+const char *
+TMailWindow::_BuildQueryString(BEntry *entry)
+{
+	BNode node(entry);
+	if (node.InitCheck() != B_OK)
+		return NULL;
 
+	uint32 mode;
+	if (node.ReadAttr(kAttrQueryInitialMode, B_INT32_TYPE, 0, (int32 *)&mode, sizeof(int32)) <= 0)
+		mode = kByNameItem;
+	
+	BString queryString;
+	switch(mode) {
+		case kByForumlaItem:
+		{
+			BString buffer;
+			if (node.ReadAttrString(kAttrQueryInitialString, &buffer) == B_OK)
+				queryString << buffer;
+			break;
+		}
+			
+		case kByNameItem:
+		{
+			BString buffer;
+			if (node.ReadAttrString(kAttrQueryInitialString, &buffer) == B_OK)
+				queryString << "(name==*" << buffer << "*)";
+			break;
+		}
+		
+		case kByAttributeItem:
+		{
+			int32 count = 1;
+			if (node.ReadAttr(kAttrQueryInitialNumAttrs, B_INT32_TYPE, 0, (int32 *)&mode, sizeof(int32)) <= 0)
+				count = 1;
+				
+			attr_info info; 
+			if (node.GetAttrInfo(kAttrQueryInitialAttrs, &info) != B_OK)
+				break;
+		
+			if (count > 1 )
+				queryString << "(";
+
+			char *buffer = new char[info.size];
+			if (node.ReadAttr(kAttrQueryInitialAttrs, B_MESSAGE_TYPE, 0, buffer, (size_t)info.size) == info.size) {
+				BMessage message;
+				if (message.Unflatten(buffer) == B_OK) {
+					for (int32 index = 0; /*index < count*/; index++) {
+
+						const char *field;
+						const char *value;
+						if (message.FindString("menuSelection", index, &field) != B_OK
+							|| message.FindString("attrViewText", index, &value) != B_OK)
+							break;
+							
+						// ignore the mime type, we'll force it to be email later
+						if (strcmp(field, "BEOS:TYPE") != 0)
+						{
+							// TODO: check if subMenu contains the type of comparison we are suppose to make here
+							queryString << "(" << field << "==\"" << value << "\")";
+
+							int32 logicMenuSelectedIndex;
+							if (message.FindInt32("logicalRelation", index, &logicMenuSelectedIndex) == B_OK) {
+								if (logicMenuSelectedIndex == 0)
+									queryString << "&&";
+								else if (logicMenuSelectedIndex == 1)
+									queryString << "||";
+							} else
+								break;
+						}
+					}
+				}
+			}
+			
+			if (count > 1 )
+				queryString << ")";
+
+			delete [] buffer;
+			break;
+		}
+			
+		default:
+			break;
+	}
+	
+	if (queryString.Length() == 0)
+		return NULL;
+		
+	// force it to check for email only		
+	if (queryString.FindFirst("text/x-email") < 0 ) {
+		BString temp;
+		temp << "(" << queryString << "&&(BEOS:TYPE==\"text/x-email\"))";
+		queryString = temp;
+	}
+	
+	char * string = (char *)malloc( queryString.Length() );
+	sprintf( string, "%s", queryString.String() );
+
+	return string;
+}
+
+
 void
 TMailWindow::BuildButtonBar()
 {
@@ -2589,7 +2771,28 @@
 				fContentView->fTextView->EnableSpellCheck(fSpelling->IsMarked());
 			}
 			break;
+			
+		case M_EDIT_QUERIES:
+		{
+			BEntry folderEntry;
+			BPath path;
+			// Get the user home directory
+			if (find_directory(B_USER_DIRECTORY, &path) != B_OK)
+				break;
+			path.Append(kQueriesDirectory);
+			if (folderEntry.SetTo(path.Path()) == B_OK && folderEntry.Exists())
+			{
+				BMessage thePackage(B_REFS_RECEIVED);
+				BMessenger tracker("application/x-vnd.Be-TRAK");
 
+				entry_ref ref;
+				folderEntry.GetRef(&ref);
+				thePackage.AddRef("refs", &ref);
+				tracker.SendMessage(&thePackage);
+			}
+			break;
+		}
+
 		default:
 			BWindow::MessageReceived(msg);
 	}
