De-cruftify Geary.Collection utility functions

Remove functions that have as-convenient methods in up-tp-date Gee,
rename ::get_first to ::first so it reads better and add API docs,
replace ::to_array_list with ::copy, since that's what's actually
needed.
This commit is contained in:
Michael Gratton 2019-11-19 14:20:42 +11:00 committed by Michael James Gratton
parent 1deae845c3
commit e4cbff8bfa
27 changed files with 135 additions and 149 deletions

View file

@ -40,7 +40,7 @@ public class Application.AttachmentManager : GLib.Object {
GLib.Cancellable? cancellable) {
if (attachments.size == 1) {
return yield save_attachment(
Geary.Collection.get_first(attachments), null, cancellable
Geary.Collection.first(attachments), null, cancellable
);
} else {
return yield save_all(attachments, cancellable);

View file

@ -813,7 +813,7 @@ public class Application.Client : Gtk.Application {
// likely still loading folders after being
// opened. Add a listener to try again later.
try {
Geary.Account first = Geary.Collection.get_first(
Geary.Account? first = Geary.Collection.first(
this.engine.get_accounts()
);
if (first != null) {
@ -1131,7 +1131,7 @@ public class Application.Client : Gtk.Application {
if (main != null) {
this.controller.unregister_window(main);
if (this.last_active_main_window == main) {
this.last_active_main_window = Geary.Collection.get_first(
this.last_active_main_window = Geary.Collection.first(
get_main_windows()
);
}

View file

@ -586,7 +586,7 @@ public class Application.MainWindow :
if (loaded.size == 1) {
// A single conversation was loaded, so ensure we
// scroll to the email in the conversation.
Geary.App.Conversation target = Geary.Collection.get_first(loaded);
Geary.App.Conversation? target = Geary.Collection.first(loaded);
ConversationListBox? current_list =
this.conversation_viewer.current_list;
if (current_list != null &&
@ -860,7 +860,7 @@ public class Application.MainWindow :
private Geary.Folder? get_first_inbox() {
Geary.Folder? inbox = null;
try {
Geary.Account first = Geary.Collection.get_first(
Geary.Account? first = Geary.Collection.first(
this.application.engine.get_accounts()
);
if (first != null) {
@ -1285,7 +1285,7 @@ public class Application.MainWindow :
case 1:
update_conversation_actions(SINGLE);
Geary.App.Conversation convo = Geary.Collection.get_first(to_select);
Geary.App.Conversation? convo = Geary.Collection.first(to_select);
// It's possible for a conversation with zero email to
// be selected, when it has just evaporated after its

View file

@ -624,24 +624,26 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface {
// Assemble the headers.
if (email.length > 0 && headers.contains("to"))
this.to = "%s,%s".printf(email, Geary.Collection.get_first(headers.get("to")));
this.to = "%s,%s".printf(
email, Geary.Collection.first(headers.get("to"))
);
else if (email.length > 0)
this.to = email;
else if (headers.contains("to"))
this.to = Geary.Collection.get_first(headers.get("to"));
this.to = Geary.Collection.first(headers.get("to"));
if (headers.contains("cc"))
this.cc = Geary.Collection.get_first(headers.get("cc"));
this.cc = Geary.Collection.first(headers.get("cc"));
if (headers.contains("bcc"))
this.bcc = Geary.Collection.get_first(headers.get("bcc"));
this.bcc = Geary.Collection.first(headers.get("bcc"));
if (headers.contains("subject"))
this.subject = Geary.Collection.get_first(headers.get("subject"));
this.subject = Geary.Collection.first(headers.get("subject"));
if (headers.contains("body"))
this.body_html = Geary.HTML.preserve_whitespace(Geary.HTML.escape_markup(
Geary.Collection.get_first(headers.get("body"))));
Geary.Collection.first(headers.get("body"))));
Gee.List<string> attachments = new Gee.LinkedList<string>();
attachments.add_all(headers.get("attach"));

View file

@ -492,8 +492,8 @@ public class ConversationListView : Gtk.TreeView, Geary.BaseInterface {
}
// only notify if different than what was previously reported
if (!Geary.Collection.are_sets_equal<Geary.App.Conversation>(
this.selected, new_selection)) {
if (this.selected.size != new_selection.size ||
!this.selected.contains_all(new_selection)) {
this.selected = new_selection;
conversations_selected(this.selected.read_only_view);
}
@ -520,18 +520,18 @@ public class ConversationListView : Gtk.TreeView, Geary.BaseInterface {
// Always returns false, so it can be used as a one-time SourceFunc
private bool update_visible_conversations() {
bool changed = false;
Gee.Set<Geary.App.Conversation> visible_conversations = get_visible_conversations();
if (current_visible_conversations != null
&& Geary.Collection.are_sets_equal<Geary.App.Conversation>(
current_visible_conversations, visible_conversations)) {
return false;
if (this.current_visible_conversations == null ||
this.current_visible_conversations.size != visible_conversations.size ||
!this.current_visible_conversations.contains_all(visible_conversations)) {
this.current_visible_conversations = visible_conversations;
visible_conversations_changed(
this.current_visible_conversations.read_only_view
);
changed = true;
}
current_visible_conversations = visible_conversations;
visible_conversations_changed(current_visible_conversations.read_only_view);
return false;
return changed;
}
private void schedule_visible_conversations_changed() {

View file

@ -678,7 +678,7 @@ public class ConversationListBox : Gtk.ListBox, Geary.BaseInterface {
id => this.conversation.contains_email_by_id(id)
).to_array_list();
valid_scroll_to.sort((a, b) => a.natural_sort_comparator(b));
var first_scroll = Geary.Collection.get_first(valid_scroll_to);
var first_scroll = Geary.Collection.first(valid_scroll_to);
if (first_scroll != null) {
foreach (Geary.Email email in all_email) {

View file

@ -132,7 +132,7 @@ public class ConversationWebView : ClientWebView {
});
controller.search(
Geary.Collection.get_first(terms),
Geary.Collection.first(terms),
WebKit.FindOptions.CASE_INSENSITIVE |
WebKit.FindOptions.WRAP_AROUND,
128

View file

@ -302,7 +302,7 @@ private class Geary.App.ConversationSet : BaseObject {
} else {
Gee.Set<Conversation> associated =
get_associated_conversations(email);
conversation = Collection.get_first<Conversation>(associated);
conversation = Collection.first(associated);
if (conversation == null) {
// Not in or related to any existing conversations, so
// create one

View file

@ -19,9 +19,9 @@ private class Geary.App.CopyOperation : Geary.App.AsyncFolderOperation {
Geary.FolderSupport.Copy? copy = folder as Geary.FolderSupport.Copy;
assert(copy != null);
Gee.List<Geary.EmailIdentifier> list
= Geary.Collection.to_array_list<Geary.EmailIdentifier>(ids);
yield copy.copy_email_async(list, destination, cancellable);
yield copy.copy_email_async(
Collection.copy(ids), destination, cancellable
);
return ids;
}
}

View file

@ -20,7 +20,7 @@ private class Geary.App.FetchOperation : Geary.App.AsyncFolderOperation {
Geary.Folder folder, Gee.Collection<Geary.EmailIdentifier> ids,
Cancellable? cancellable) throws Error {
assert(result == null);
Geary.EmailIdentifier? id = Geary.Collection.get_first(ids);
Geary.EmailIdentifier? id = Collection.first(ids);
assert(id != null);
result = yield folder.fetch_email_async(

View file

@ -21,9 +21,9 @@ private class Geary.App.MarkOperation : Geary.App.AsyncFolderOperation {
Geary.FolderSupport.Mark? mark = folder as Geary.FolderSupport.Mark;
assert(mark != null);
Gee.List<Geary.EmailIdentifier> list
= Geary.Collection.to_array_list<Geary.EmailIdentifier>(ids);
yield mark.mark_email_async(list, flags_to_add, flags_to_remove, cancellable);
yield mark.mark_email_async(
Collection.copy(ids), flags_to_add, flags_to_remove, cancellable
);
return ids;
}
}

View file

@ -319,8 +319,7 @@ private class Geary.ImapDB.SearchFolder : Geary.SearchFolder, Geary.FolderSuppor
yield folder.open_async(Geary.Folder.OpenFlags.NONE, cancellable);
open = true;
yield remove.remove_email_async(
Geary.Collection.to_array_list<Geary.EmailIdentifier>(ids),
cancellable
Collection.copy(ids), cancellable
);
} finally {
if (open) {

View file

@ -73,7 +73,7 @@ private class Geary.ImapEngine.CreateEmail : SendReplayOperation {
);
if (results.size > 0) {
this.created_id = Collection.get_first<Email>(results.keys).id;
this.created_id = Collection.first(results.keys).id;
} else {
// Something went wrong creating/merging the message,
// so pretend we don't know what its UID is so the

View file

@ -397,9 +397,13 @@ internal class Geary.Imap.AccountSession : Geary.Imap.SessionObject {
cancellable
);
assert(responses.size == 1);
return Geary.Collection.get_first(responses.values);
var response = Collection.first(responses.values);
if (response == null) {
throw new ImapError.SERVER_ERROR(
"No status response received from server"
);
}
return response;
}
private async Gee.Map<Command, StatusResponse>

View file

@ -688,7 +688,8 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject {
debug("Unable to retrieve COPYUID UIDs: %s", ierr.message);
}
if (!Collection.is_empty(src_uids) && !Collection.is_empty(dst_uids)) {
if (src_uids != null && !src_uids.is_empty &&
dst_uids != null && !dst_uids.is_empty) {
Gee.Map<UID, UID> copyuids = new Gee.HashMap<UID, UID>();
int ctr = 0;
for (;;) {

View file

@ -1281,7 +1281,7 @@ public class Geary.Imap.ClientSession : BaseObject {
check_unsupported_send_command(cmd);
// only issue one event to the state machine for all commands; either all succeed or all fail
MachineParams params = new MachineParams(Geary.Collection.get_first(cmds));
MachineParams params = new MachineParams(Collection.first(cmds));
fsm.issue(Event.SEND_CMD, null, params);
if (params.err != null)

View file

@ -184,19 +184,11 @@ public class Geary.RFC822.MailboxAddresses :
}
public bool equal_to(MailboxAddresses other) {
if (this == other)
return true;
if (addrs.size != other.addrs.size)
return false;
Gee.HashSet<RFC822.MailboxAddress> first = new Gee.HashSet<RFC822.MailboxAddress>();
first.add_all(addrs);
Gee.HashSet<RFC822.MailboxAddress> second = new Gee.HashSet<RFC822.MailboxAddress>();
second.add_all(other.addrs);
return Collection.are_sets_equal<RFC822.MailboxAddress>(first, second);
return (
this == other ||
(this.addrs.size == other.addrs.size &&
this.addrs.contains_all(other.addrs))
);
}
/**

View file

@ -428,7 +428,7 @@ public class Geary.Smtp.ClientService : Geary.ClientService {
null, 1, REFERENCES, NONE, cancellable
);
if (list != null && !list.is_empty) {
Email listed = Collection.get_first<Email>(list);
Email listed = Collection.first(list);
if (listed.message_id != null &&
listed.message_id.equal_to(id)) {
break;

View file

@ -8,9 +8,6 @@ namespace Geary.Collection {
public delegate uint8 ByteTransformer(uint8 b);
public inline bool is_empty(Gee.Collection? c) {
return c == null || c.size == 0;
}
/** Returns a modifiable collection containing a single element. */
public Gee.Collection<T> single<T>(T element) {
@ -26,80 +23,34 @@ namespace Geary.Collection {
return single;
}
// A substitute for ArrayList<G>.wrap() for compatibility with older versions of Gee.
public Gee.ArrayList<G> array_list_wrap<G>(G[] a, owned Gee.EqualDataFunc<G>? equal_func = null) {
Gee.ArrayList<G> list = new Gee.ArrayList<G>((owned) equal_func);
add_all_array<G>(list, a);
return list;
/** Returns a copy of the given collection in a new collection. */
public Gee.Collection<V> copy<V>(Gee.Collection<V> original) {
// Use a linked list, the returned value can't be accessed by
// index anyway
var copy = new Gee.LinkedList<V>();
copy.add_all(original);
return copy;
}
public Gee.ArrayList<G> to_array_list<G>(Gee.Collection<G> c) {
Gee.ArrayList<G> list = new Gee.ArrayList<G>();
list.add_all(c);
return list;
}
public Gee.HashMap<Key, Value> to_hash_map<Key, Value>(
Gee.Collection<Value> c, Gee.MapFunc<Key, Value> key_selector) {
Gee.HashMap<Key, Value> map = new Gee.HashMap<Key, Value>();
foreach (Value v in c) {
map.set(key_selector(v), v);
}
return map;
}
public void add_all_array<G>(Gee.Collection<G> c, G[] ar) {
foreach (G g in ar) {
c.add(g);
}
}
public G? get_first<G>(Gee.Collection<G> c) {
/** Returns the first element from a collection. */
public G? first<G>(Gee.Collection<G> c) {
Gee.Iterator<G> iter = c.iterator();
return iter.next() ? iter.get() : null;
}
/**
* Returns the first element in the Collection that passes the Predicte function.
*
* The Collection is walked in Iterator order.
*/
public G? find_first<G>(Gee.Collection<G> c, owned Gee.Predicate<G> pred) {
Gee.Iterator<G> iter = c.iterator();
while (iter.next()) {
if (pred(iter.get()))
return iter.get();
}
return null;
}
public bool are_sets_equal<G>(Gee.Set<G> a, Gee.Set<G> b) {
if (a.size != b.size) {
return false;
}
foreach (G element in a) {
if (!b.contains(element)) {
return false;
}
}
return true;
}
/**
* Removes all elements from the Collection that do pass the Predicate function.
* Removes all elements that pass the given predicate.
*
* Note that this modifies the supplied Collection.
*/
public Gee.Collection<G> remove_if<G>(Gee.Collection<G> c, owned Gee.Predicate<G> pred) {
public Gee.Collection<G> remove_if<G>(Gee.Collection<G> c,
owned Gee.Predicate<G> pred) {
Gee.Iterator<G> iter = c.iterator();
while (iter.next()) {
if (pred(iter.get()))
if (pred(iter.get())) {
iter.remove();
}
}
return c;
}

View file

@ -126,20 +126,20 @@ public class Geary.ConfigFile {
}
public Gee.List<string> get_string_list(string key) {
var strs = new Gee.ArrayList<string>();
try {
string[] list = this.backing.get_string_list(this.name, key);
if (list.length > 0)
return Geary.Collection.array_list_wrap<string>(list);
strs.add_all_array(this.backing.get_string_list(this.name, key));
} catch (GLib.KeyFileError err) {
// Oh well
}
return new Gee.ArrayList<string>();
return strs;
}
public Gee.List<string> get_required_string_list(string key)
throws GLib.KeyFileError {
string[] list = this.backing.get_string_list(this.name, key);
return Geary.Collection.array_list_wrap<string>(list);
var strs = new Gee.ArrayList<string>();
strs.add_all_array(this.backing.get_string_list(this.name, key));
return strs;
}
public void set_string_list(string key, Gee.List<string> value) {

View file

@ -20,7 +20,9 @@ namespace Geary {
va_list args = va_list();
G arg = g;
Gee.ArrayList<G> list = new Gee.ArrayList<G>();
// Use a linked list since we will only ever be iterating over
// it
var list = new Gee.LinkedList<G>();
do {
list.add(arg);
} while((arg = args.arg()) != null);
@ -31,8 +33,12 @@ namespace Geary {
/**
* Take an array of items and return a Geary.Iterable for convenience.
*/
public Geary.Iterable<G> iterate_array<G>(G[] a) {
return Geary.traverse<G>(Geary.Collection.array_list_wrap<G>(a));
public Geary.Iterable<G> iterate_array<G>(G[] a, owned Gee.EqualDataFunc<G>? equal_func = null) {
// Use a linked list since we will only ever be iterating over
// it
var list = new Gee.LinkedList<G>((owned) equal_func);
list.add_all_array(a);
return Geary.traverse<G>(list);
}
}

View file

@ -12,12 +12,10 @@ namespace Geary.ObjectUtils {
public Gee.List<Binding>? mirror_properties(Object source, Object dest, BindingFlags
flags = GLib.BindingFlags.DEFAULT | GLib.BindingFlags.SYNC_CREATE) {
// Make sets of both object's properties.
Gee.HashSet<ParamSpec> source_properties = new Gee.HashSet<ParamSpec>();
Collection.add_all_array<ParamSpec>(source_properties,
source.get_class().list_properties());
Gee.HashSet<ParamSpec> dest_properties = new Gee.HashSet<ParamSpec>();
Collection.add_all_array<ParamSpec>(dest_properties,
dest.get_class().list_properties());
Gee.HashSet<ParamSpec> source_properties =
iterate_array(source.get_class().list_properties()).to_hash_set();
Gee.HashSet<ParamSpec> dest_properties =
iterate_array(dest.get_class().list_properties()).to_hash_set();
// Remove properties from source_properties that are not in both sets.
source_properties.retain_all(dest_properties);

View file

@ -133,7 +133,7 @@ class Geary.App.ConversationMonitorTest : TestCase {
assert_non_null(monitor.window_lowest, "Lowest window id");
assert_equal(e1.id, monitor.window_lowest, "Lowest window id");
Conversation c1 = Geary.Collection.get_first(monitor.read_only_view);
Conversation c1 = Collection.first(monitor.read_only_view);
assert_equal(e1, c1.get_email_by_id(e1.id), "Email not present in conversation");
}
@ -175,7 +175,7 @@ class Geary.App.ConversationMonitorTest : TestCase {
assert_non_null(monitor.window_lowest, "Lowest window id");
assert_equal(e2.id, monitor.window_lowest, "Lowest window id");
Conversation c1 = Geary.Collection.get_first(monitor.read_only_view);
Conversation c1 = Collection.first(monitor.read_only_view);
assert_equal(e1, c1.get_email_by_id(e1.id), "Related email not present in conversation");
assert_equal(e2, c1.get_email_by_id(e2.id), "In folder not present in conversation");
}
@ -329,7 +329,7 @@ class Geary.App.ConversationMonitorTest : TestCase {
assert_int(1, monitor.size, "Conversation count");
Conversation c1 = Geary.Collection.get_first(monitor.read_only_view);
Conversation c1 = Collection.first(monitor.read_only_view);
assert_int(2, c1.get_count(), "Conversation message count");
assert_equal(e3, c1.get_email_by_id(e3.id),
"Appended email not present in conversation");

View file

@ -116,7 +116,7 @@ class Geary.App.ConversationSetTest : TestCase {
assert(this.test.get_email_count() == 1);
assert(added.size == 1);
assert(Geary.Collection.get_first(added).get_email_by_id(e1.id) == e1);
assert(Collection.first(added).get_email_by_id(e1.id) == e1);
assert(appended.size == 0);
assert(removed.is_empty);
@ -165,7 +165,7 @@ class Geary.App.ConversationSetTest : TestCase {
assert(added.size == 1);
Conversation convo1 = Geary.Collection.get_first(added);
Conversation convo1 = Collection.first(added);
assert(convo1.get_email_by_id(e1.id) == e1);
assert(convo1.get_email_by_id(e2.id) == e2);
@ -195,7 +195,7 @@ class Geary.App.ConversationSetTest : TestCase {
assert(added.is_empty);
assert(appended.size == 1);
Conversation convo2 = Geary.Collection.get_first(appended.get_keys());
Conversation convo2 = Collection.first(appended.get_keys());
assert(convo2.get_email_by_id(e1.id) == e1);
assert(convo2.get_email_by_id(e2.id) == e2);
assert(convo2.get_email_by_id(e3.id) == e3);
@ -234,7 +234,7 @@ class Geary.App.ConversationSetTest : TestCase {
assert(added.is_empty);
assert(appended.size == 1);
Conversation convo = Geary.Collection.get_first(appended.get_keys());
Conversation convo = Collection.first(appended.get_keys());
assert(convo.get_email_by_id(e1.id) == e1);
assert(convo.get_email_by_id(e2.id) == e2);

View file

@ -73,7 +73,7 @@ class Geary.ContactHarvesterImplTest : TestCase {
Gee.Collection<Contact> contacts = update_call.called_arg<Gee.Collection<Contact>>(0);
assert_int(1, contacts.size, "contacts length");
Contact? created = Collection.get_first<Contact>(contacts) as Contact;
Contact? created = Collection.first(contacts) as Contact;
assert_non_null(created, "contacts contents");
assert_string("Test", created.real_name);
@ -121,7 +121,7 @@ class Geary.ContactHarvesterImplTest : TestCase {
this.store.assert_expectations();
Gee.Collection<Contact> contacts = update_call.called_arg<Gee.Collection<Contact>>(0);
Contact? created = Collection.get_first<Contact>(contacts) as Contact;
Contact? created = Collection.first(contacts) as Contact;
assert_int(
Contact.Importance.SEEN,
created.highest_importance,
@ -150,7 +150,7 @@ class Geary.ContactHarvesterImplTest : TestCase {
this.store.assert_expectations();
Gee.Collection<Contact> contacts = update_call.called_arg<Gee.Collection<Contact>>(0);
Contact? created = Collection.get_first<Contact>(contacts) as Contact;
Contact? created = Collection.first(contacts) as Contact;
assert_int(
Contact.Importance.SENT_TO,
created.highest_importance,
@ -179,7 +179,7 @@ class Geary.ContactHarvesterImplTest : TestCase {
this.store.assert_expectations();
Gee.Collection<Contact> contacts = update_call.called_arg<Gee.Collection<Contact>>(0);
Contact? created = Collection.get_first<Contact>(contacts) as Contact;
Contact? created = Collection.first(contacts) as Contact;
assert_int(
Contact.Importance.RECEIVED_FROM,
created.highest_importance,

View file

@ -125,7 +125,7 @@ class Geary.ContactStoreImplTest : TestCase {
);
assert_int(1, results.size, "results.size");
Contact search_hit = Collection.get_first(results);
Contact search_hit = Collection.first(results);
assert_string("Test@example.com", search_hit.email, "Existing email");
assert_string("test@example.com", search_hit.normalized_email, "Existing normalized_email");
assert_string("Test Name", search_hit.real_name, "Existing real_name");
@ -146,7 +146,7 @@ class Geary.ContactStoreImplTest : TestCase {
);
assert_int(1, results.size, "results.size");
Contact search_hit = Collection.get_first(results);
Contact search_hit = Collection.first(results);
assert_string("Test@example.com", search_hit.email, "Existing email");
assert_string("test@example.com", search_hit.normalized_email, "Existing normalized_email");
assert_string("Test Name", search_hit.real_name, "Existing real_name");
@ -180,7 +180,7 @@ class Geary.ContactStoreImplTest : TestCase {
);
assert_int(1, results.size, "results.size");
Contact search_hit = Collection.get_first(results);
Contact search_hit = Collection.first(results);
assert_string("Germán", search_hit.real_name, "Existing real_name");
}
@ -211,7 +211,7 @@ class Geary.ContactStoreImplTest : TestCase {
);
assert_int(1, results.size, "results.size");
Contact search_hit = Collection.get_first(results);
Contact search_hit = Collection.first(results);
assert_string("年収1億円目指せ", search_hit.real_name, "Existing real_name");
}

View file

@ -12,6 +12,7 @@ class Geary.RFC822.MailboxAddressesTest : TestCase {
add_test("from_rfc822_string_encoded", from_rfc822_string_encoded);
add_test("from_rfc822_string_quoted", from_rfc822_string_quoted);
add_test("to_rfc822_string", to_rfc822_string);
add_test("equal_to", equal_to);
}
public void from_rfc822_string_encoded() throws Error {
@ -49,6 +50,38 @@ class Geary.RFC822.MailboxAddressesTest : TestCase {
.to_rfc822_string() == "test1@example.com, test2@example.com");
}
public void equal_to() throws Error {
var mailboxes_a = new_addreses({ "test1@example.com" });
var mailboxes_b = new_addreses({ "test1@example.com" });
var mailboxes_c = new_addreses({ "test2@example.com" });
assert_true(mailboxes_a.equal_to(mailboxes_a));
assert_true(mailboxes_a.equal_to(mailboxes_b));
assert_false(mailboxes_a.equal_to(mailboxes_c));
assert_true(
new_addreses({ "test1@example.com", "test2@example.com" }).equal_to(
new_addreses({ "test1@example.com", "test2@example.com" })
)
);
assert_true(
new_addreses({ "test1@example.com", "test2@example.com" }).equal_to(
new_addreses({ "test2@example.com", "test1@example.com" })
)
);
assert_false(
new_addreses({ "test1@example.com", "test2@example.com" }).equal_to(
new_addreses({ "test1@example.com" })
)
);
assert_false(
new_addreses({ "test1@example.com", "test2@example.com" }).equal_to(
new_addreses({ "test1@example.com", "test3@example.com" })
)
);
}
private MailboxAddresses new_addreses(string[] address_strings) {
Gee.List<MailboxAddress> addresses = new Gee.LinkedList<MailboxAddress>();
foreach (string address in address_strings) {