changeset 4451:1a35d53c18fc HEAD

Array API redesigned to work using unions. It now provides type safety without having to enable DEBUG, as long as the compiler supports typeof(). Its API changed a bit. It now allows directly accessing the array contents, although that's not necessarily recommended. Changed existing array usage to be type safe in a bit more places. Removed array_t completely. Also did s/modifyable/modifiable/.
author Timo Sirainen <tss@iki.fi>
date Wed, 28 Jun 2006 16:10:25 +0300
parents 14b10f7ea70e
children 66fc4c35a8de
files src/auth/auth-master-listener.c src/auth/auth-master-listener.h src/auth/auth-request-handler.c src/auth/auth-worker-server.c src/auth/mech-gssapi.c src/auth/userdb-static.c src/dict/dict-server.c src/imap/client.h src/imap/cmd-list.c src/imap/commands-util.c src/imap/commands-util.h src/imap/commands.c src/imap/imap-fetch.c src/imap/imap-fetch.h src/lib-auth/auth-client.c src/lib-dict/dict.c src/lib-imap/imap-base-subject.c src/lib-index/mail-cache-compress.c src/lib-index/mail-cache-lookup.c src/lib-index/mail-cache-private.h src/lib-index/mail-cache-transaction.c src/lib-index/mail-index-private.h src/lib-index/mail-index-sync-ext.c src/lib-index/mail-index-sync-private.h src/lib-index/mail-index-sync-update.c src/lib-index/mail-index-sync.c src/lib-index/mail-index-transaction-private.h src/lib-index/mail-index-transaction-view.c src/lib-index/mail-index-transaction.c src/lib-index/mail-index-view-private.h src/lib-index/mail-index-view-sync.c src/lib-index/mail-index-view.c src/lib-index/mail-index.c src/lib-index/mail-index.h src/lib-index/mail-transaction-log-append.c src/lib-mail/mail-types.h src/lib-mail/message-body-search.c src/lib-mail/message-header-search.c src/lib-sql/driver-mysql.c src/lib-sql/sql-api-private.h src/lib-sql/sql-api.c src/lib-storage/index/dbox/dbox-keywords.c src/lib-storage/index/dbox/dbox-save.c src/lib-storage/index/dbox/dbox-storage.h src/lib-storage/index/dbox/dbox-sync-expunge.c src/lib-storage/index/dbox/dbox-sync-full.c src/lib-storage/index/dbox/dbox-sync.c src/lib-storage/index/dbox/dbox-sync.h src/lib-storage/index/dbox/dbox-uidlist.c src/lib-storage/index/dbox/dbox-uidlist.h src/lib-storage/index/index-mail-headers.c src/lib-storage/index/index-mail.c src/lib-storage/index/index-mail.h src/lib-storage/index/index-sort.c src/lib-storage/index/index-storage.h src/lib-storage/index/index-sync.c src/lib-storage/index/maildir/maildir-keywords.c src/lib-storage/index/maildir/maildir-save.c src/lib-storage/index/maildir/maildir-storage.c src/lib-storage/index/maildir/maildir-storage.h src/lib-storage/index/maildir/maildir-sync.c src/lib-storage/index/maildir/maildir-uidlist.c src/lib-storage/index/mbox/mbox-save.c src/lib-storage/index/mbox/mbox-sync-parse.c src/lib-storage/index/mbox/mbox-sync-private.h src/lib-storage/index/mbox/mbox-sync-rewrite.c src/lib-storage/index/mbox/mbox-sync-update.c src/lib-storage/index/mbox/mbox-sync.c src/lib-storage/mail-storage-private.h src/lib-storage/mail-storage.c src/lib-storage/mail-storage.h src/lib/array-decl.h src/lib/array.h src/lib/buffer.c src/lib/buffer.h src/lib/ioloop-epoll.c src/lib/istream.c src/lib/istream.h src/lib/lib.h src/lib/module-dir.c src/lib/seq-range-array.c src/lib/seq-range-array.h src/lib/str.c src/lib/str.h src/master/mail-process.c src/master/master-settings.h src/plugins/acl/acl-backend-vfile.c src/plugins/acl/acl-cache.c src/plugins/acl/acl-mailbox.c src/plugins/acl/acl-plugin.h src/plugins/quota/quota-dirsize.c src/plugins/quota/quota-private.h src/plugins/quota/quota-storage.c src/plugins/quota/quota.c src/plugins/trash/trash-plugin.c src/plugins/zlib/zlib-plugin.c
diffstat 96 files changed, 493 insertions(+), 531 deletions(-) [+]
line wrap: on
line diff
--- a/src/auth/auth-master-listener.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/auth/auth-master-listener.c	Wed Jun 28 16:10:25 2006 +0300
@@ -21,7 +21,7 @@
 	struct io *io;
 };
 
-static array_t ARRAY_DEFINE(master_listeners, struct auth_master_listener *);
+static ARRAY_DEFINE(master_listeners, struct auth_master_listener *);
 
 struct auth_master_listener *auth_master_listener_create(struct auth *auth)
 {
@@ -71,15 +71,15 @@
 		}
 	}
 
-	sockets = array_get_modifyable(&listener->sockets, &count);
+	sockets = array_get_modifiable(&listener->sockets, &count);
 	for (i = count; i > 0; i--)
 		auth_master_listener_socket_free(sockets[i-1]);
 
-	masters = array_get_modifyable(&listener->masters, &count);
+	masters = array_get_modifiable(&listener->masters, &count);
 	for (i = count; i > 0; i--)
 		auth_master_connection_destroy(&masters[i-1]);
 
-	clients = array_get_modifyable(&listener->clients, &count);
+	clients = array_get_modifiable(&listener->clients, &count);
 	for (i = count; i > 0; i--)
 		auth_client_connection_destroy(&clients[i-1]);
 
@@ -177,7 +177,7 @@
         struct auth_master_listener **listeners;
 	unsigned int i, count;
 
-	listeners = array_get_modifyable(&master_listeners, &count);
+	listeners = array_get_modifiable(&master_listeners, &count);
 	for (i = count; i > 0; i--)
 		auth_master_listener_destroy(listeners[i-1]);
 	array_free(&master_listeners);
--- a/src/auth/auth-master-listener.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/auth/auth-master-listener.h	Wed Jun 28 16:10:25 2006 +0300
@@ -10,9 +10,9 @@
 	struct auth *auth;
 	unsigned int pid;
 
-	array_t ARRAY_DEFINE(sockets, struct auth_master_listener_socket *);
-	array_t ARRAY_DEFINE(masters, struct auth_master_connection *);
-	array_t ARRAY_DEFINE(clients, struct auth_client_connection *);
+	ARRAY_DEFINE(sockets, struct auth_master_listener_socket *);
+	ARRAY_DEFINE(masters, struct auth_master_connection *);
+	ARRAY_DEFINE(clients, struct auth_client_connection *);
 
 	struct timeout *to_clients;
 };
--- a/src/auth/auth-request-handler.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/auth/auth-request-handler.c	Wed Jun 28 16:10:25 2006 +0300
@@ -454,7 +454,7 @@
 	struct auth_request **auth_request;
 	size_t i, size;
 
-	auth_request = buffer_get_modifyable_data(auth_failures_buf, &size);
+	auth_request = buffer_get_modifiable_data(auth_failures_buf, &size);
 	size /= sizeof(*auth_request);
 
 	for (i = 0; i < size; i++) {
--- a/src/auth/auth-worker-server.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/auth/auth-worker-server.c	Wed Jun 28 16:10:25 2006 +0300
@@ -99,7 +99,7 @@
 	size_t i, size;
 	const char *reply;
 
-	connp = buffer_get_modifyable_data(connections, &size);
+	connp = buffer_get_modifiable_data(connections, &size);
 	size /= sizeof(*connp);
 
 	for (i = 0; i < size; i++) {
@@ -114,7 +114,7 @@
 		idle_count--;
 
 	/* abort all pending requests */
-	request = buffer_get_modifyable_data(conn->requests, &size);
+	request = buffer_get_modifiable_data(conn->requests, &size);
 	size /= sizeof(*request);
 
 	reply = t_strdup_printf("FAIL\t%d", PASSDB_RESULT_INTERNAL_FAILURE);
@@ -143,7 +143,7 @@
 	struct auth_worker_request *request;
 	size_t i, size;
 
-	request = buffer_get_modifyable_data(conn->requests, &size);
+	request = buffer_get_modifiable_data(conn->requests, &size);
 	size /= sizeof(*request);
 
 	for (i = 0; i < size; i++) {
@@ -159,7 +159,7 @@
 	struct auth_worker_connection **conn, *best;
 	size_t i, size, outbuf_size, best_size;
 
-	conn = buffer_get_modifyable_data(connections, &size);
+	conn = buffer_get_modifiable_data(connections, &size);
 	size /= sizeof(*conn);
 
 	if (idle_count > 0) {
@@ -245,7 +245,7 @@
         struct auth_worker_request *request;
 	size_t i, size;
 
-	request = buffer_get_modifyable_data(conn->requests, &size);
+	request = buffer_get_modifiable_data(conn->requests, &size);
 	size /= sizeof(*request);
 
 	for (i = 0; i < size; i++) {
@@ -320,7 +320,7 @@
 	struct auth_worker_connection **conn;
 	size_t i, size;
 
-	conn = buffer_get_modifyable_data(connections, &size);
+	conn = buffer_get_modifiable_data(connections, &size);
 	size /= sizeof(*conn);
 
 	if (idle_count <= 1)
@@ -373,7 +373,7 @@
 		return;
 
 	while (connections->used > 0) {
-		connp = buffer_get_modifyable_data(connections, NULL);
+		connp = buffer_get_modifiable_data(connections, NULL);
 		auth_worker_destroy(*connp);
 	}
 	buffer_free(connections);
--- a/src/auth/mech-gssapi.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/auth/mech-gssapi.c	Wed Jun 28 16:10:25 2006 +0300
@@ -106,7 +106,7 @@
 		"Obtaining credentials for %s", str_c(principal_name));
 
 	inbuf.length = str_len(principal_name);
-	inbuf.value = str_c_modifyable(principal_name);
+	inbuf.value = str_c_modifiable(principal_name);
 
 	major_status = gss_import_name(&minor_status, &inbuf, 
 				       GSS_C_NT_HOSTBASED_SERVICE,
--- a/src/auth/userdb-static.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/auth/userdb-static.c	Wed Jun 28 16:10:25 2006 +0300
@@ -14,7 +14,7 @@
 struct static_userdb_module {
 	struct userdb_module module;
 
-	array_t ARRAY_DEFINE(template, const char *);
+	ARRAY_DEFINE(template, const char *);
 };
 
 static void static_lookup(struct auth_request *auth_request,
--- a/src/dict/dict-server.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/dict/dict-server.c	Wed Jun 28 16:10:25 2006 +0300
@@ -33,7 +33,7 @@
 
 	/* There are only a few transactions per client, so keeping them in
 	   array is fast enough */
-	array_t ARRAY_DEFINE(transactions, struct dict_server_transaction);
+	ARRAY_DEFINE(transactions, struct dict_server_transaction);
 };
 
 struct dict_server {
@@ -111,7 +111,7 @@
 	if (!array_is_created(&conn->transactions))
 		return NULL;
 
-	transactions = array_get_modifyable(&conn->transactions, &count);
+	transactions = array_get_modifiable(&conn->transactions, &count);
 	for (i = 0; i < count; i++) {
 		if (transactions[i].id == id)
 			return &transactions[i];
--- a/src/imap/client.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/imap/client.h	Wed Jun 28 16:10:25 2006 +0300
@@ -11,7 +11,7 @@
 struct mailbox_keywords {
 	pool_t pool; /* will be p_clear()ed when changed */
 
-	array_t ARRAY_DEFINE(keywords, const char *);
+	ARRAY_DEFINE(keywords, const char *);
 };
 
 struct client_command_context {
--- a/src/imap/cmd-list.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/imap/cmd-list.c	Wed Jun 28 16:10:25 2006 +0300
@@ -127,7 +127,7 @@
 		str_append(name_str, list->name);
 
 		if (ctx->ns->sep != ctx->ns->real_sep) {
-                        char *p = str_c_modifyable(name_str);
+                        char *p = str_c_modifiable(name_str);
 			for (; *p != '\0'; p++) {
 				if (*p == ctx->ns->real_sep)
 					*p = ctx->ns->sep;
--- a/src/imap/commands-util.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/imap/commands-util.c	Wed Jun 28 16:10:25 2006 +0300
@@ -246,9 +246,8 @@
 	return TRUE;
 }
 
-static const char *get_keywords_string(const array_t *keywords)
+static const char *get_keywords_string(const ARRAY_TYPE(keywords) *keywords)
 {
-	ARRAY_SET_TYPE(keywords, const char *);
 	string_t *str;
 	const char *const *names;
 	unsigned int i, count;
@@ -268,7 +267,7 @@
 #define SYSTEM_FLAGS "\\Answered \\Flagged \\Deleted \\Seen \\Draft"
 
 void client_send_mailbox_flags(struct client *client, struct mailbox *box,
-			       const array_t *keywords)
+			       const ARRAY_TYPE(keywords) *keywords)
 {
 	const char *str;
 
@@ -288,9 +287,8 @@
 }
 
 bool client_save_keywords(struct mailbox_keywords *dest,
-			  const array_t *keywords)
+			  const ARRAY_TYPE(keywords) *keywords)
 {
-	ARRAY_SET_TYPE(keywords, const char *);
 	const char *const *names, *const *old_names;
 	unsigned int i, count, old_count;
 	bool changed;
--- a/src/imap/commands-util.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/imap/commands-util.h	Wed Jun 28 16:10:25 2006 +0300
@@ -44,12 +44,12 @@
 
 /* Send FLAGS + PERMANENTFLAGS to client. */
 void client_send_mailbox_flags(struct client *client, struct mailbox *box,
-			       const array_t *keywords);
+			       const ARRAY_TYPE(keywords) *keywords);
 
 /* Copy keywords into dest. dest must have been initialized. Returns TRUE if
    keywords changed. */
 bool client_save_keywords(struct mailbox_keywords *dest,
-			  const array_t *keywords);
+			  const ARRAY_TYPE(keywords) *keywords);
 
 bool mailbox_equals(struct mailbox *box1, struct mail_storage *storage2,
 		    const char *name2);
--- a/src/imap/commands.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/imap/commands.c	Wed Jun 28 16:10:25 2006 +0300
@@ -118,7 +118,7 @@
 	void *base;
 	size_t size;
 
-	base = buffer_get_modifyable_data(cmdbuf, &size);
+	base = buffer_get_modifiable_data(cmdbuf, &size);
 	size /= sizeof(struct command);
 
 	if (cmdbuf_unsorted) {
--- a/src/imap/imap-fetch.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/imap/imap-fetch.c	Wed Jun 28 16:10:25 2006 +0300
@@ -35,7 +35,7 @@
 		fetch_handlers = buffer_create_dynamic(default_pool, 128);
 	buffer_append(fetch_handlers, handlers, sizeof(*handlers) * count);
 
-	data = buffer_get_modifyable_data(fetch_handlers, &size);
+	data = buffer_get_modifiable_data(fetch_handlers, &size);
 	qsort(data, size / sizeof(*handlers), sizeof(*handlers),
 	      imap_fetch_handler_cmp);
 }
--- a/src/imap/imap-fetch.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/imap/imap-fetch.h	Wed Jun 28 16:10:25 2006 +0300
@@ -37,7 +37,7 @@
 	buffer_t *all_headers_buf;
         struct mailbox_header_lookup_ctx *all_headers_ctx;
 
-	array_t ARRAY_DEFINE(handlers, struct imap_fetch_context_handler);
+	ARRAY_DEFINE(handlers, struct imap_fetch_context_handler);
 	unsigned int buffered_handlers_count;
 
 	struct mail *cur_mail;
--- a/src/lib-auth/auth-client.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-auth/auth-client.c	Wed Jun 28 16:10:25 2006 +0300
@@ -43,7 +43,7 @@
 
 	*_client = NULL;
 
-	mech = buffer_get_modifyable_data(client->available_auth_mechs, &size);
+	mech = buffer_get_modifiable_data(client->available_auth_mechs, &size);
 	size /= sizeof(*mech);
 	for (i = 0; i < size; i++)
 		i_free(mech[i].name);
--- a/src/lib-dict/dict.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-dict/dict.c	Wed Jun 28 16:10:25 2006 +0300
@@ -5,7 +5,7 @@
 #include "dict-sql.h"
 #include "dict-private.h"
 
-static array_t ARRAY_DEFINE(dict_classes, struct dict *);
+static ARRAY_DEFINE(dict_classes, struct dict *);
 
 static struct dict *dict_class_lookup(const char *name)
 {
--- a/src/lib-imap/imap-base-subject.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-imap/imap-base-subject.c	Wed Jun 28 16:10:25 2006 +0300
@@ -32,7 +32,7 @@
 	if (size > 0) {
 		/* @UNSAFE: uppercase it. Current draft specifies that we
 		   should touch only ASCII. */
-		buf_data = buffer_get_modifyable_data(buf, &used_size);
+		buf_data = buffer_get_modifiable_data(buf, &used_size);
 		for (; pos < used_size; pos++) {
 			if (buf_data[pos] >= 'a' && buf_data[pos] <= 'z')
 				buf_data[pos] = buf_data[pos] - 'a' + 'A';
@@ -47,7 +47,7 @@
 	char *data, *dest;
 	bool last_lwsp;
 
-	data = buffer_get_modifyable_data(buf, NULL);
+	data = buffer_get_modifiable_data(buf, NULL);
 
 	/* check if we need to do anything */
 	while (*data != '\0') {
@@ -77,7 +77,7 @@
 	}
 	*dest = '\0';
 
-	data = buffer_get_modifyable_data(buf, NULL);
+	data = buffer_get_modifiable_data(buf, NULL);
 	buffer_set_used_size(buf, (size_t) (dest - data)+1);
 }
 
--- a/src/lib-index/mail-cache-compress.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-index/mail-cache-compress.c	Wed Jun 28 16:10:25 2006 +0300
@@ -28,7 +28,7 @@
 	unsigned int i, buf_data_size;
 	size_t pos, buf_size;
 
-	buf_data = buffer_get_modifyable_data(buffer, &buf_size);
+	buf_data = buffer_get_modifiable_data(buffer, &buf_size);
 	for (pos = sizeof(struct mail_cache_record); pos < buf_size; ) {
 		buf_field = *((uint32_t *)PTR_OFFSET(buf_data, pos));
 		pos += sizeof(uint32_t);
@@ -165,7 +165,7 @@
 		buffer_set_used_size(ctx.buffer, 0);
 
 		if (++ctx.field_seen_value == 0) {
-			memset(buffer_get_modifyable_data(ctx.field_seen, NULL),
+			memset(buffer_get_modifiable_data(ctx.field_seen, NULL),
 			       0, buffer_get_size(ctx.field_seen));
 			ctx.field_seen_value++;
 		}
--- a/src/lib-index/mail-cache-lookup.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-index/mail-cache-lookup.c	Wed Jun 28 16:10:25 2006 +0300
@@ -248,7 +248,7 @@
 
 	if (++view->cached_exists_value == 0) {
 		/* wrapped, we'll have to clear the buffer */
-		memset(buffer_get_modifyable_data(view->cached_exists_buf,
+		memset(buffer_get_modifiable_data(view->cached_exists_buf,
 						  NULL), 0,
 		       buffer_get_size(view->cached_exists_buf));
 		view->cached_exists_value++;
@@ -466,7 +466,7 @@
 		buffer_write(buf, fields[i], &one, 1);
                 ctx.fields[i] = fields[i];
 	}
-	ctx.fields_found = buffer_get_modifyable_data(buf, NULL);
+	ctx.fields_found = buffer_get_modifiable_data(buf, NULL);
 
 	ctx.data = buffer_create_dynamic(pool_datastack_create(), 256);
 
@@ -486,7 +486,7 @@
 		}
 	}
 
-	data = buffer_get_modifyable_data(ctx.data, &size);
+	data = buffer_get_modifiable_data(ctx.data, &size);
 	size /= sizeof(*data);
 	qsort(data, size, sizeof(*data), header_lookup_data_cmp);
 
--- a/src/lib-index/mail-cache-private.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-index/mail-cache-private.h	Wed Jun 28 16:10:25 2006 +0300
@@ -160,7 +160,7 @@
 	uint32_t trans_seq1, trans_seq2;
 
 	/* temporary array, just to avoid mallocs. */
-	array_t ARRAY_DEFINE(tmp_offsets, uint32_t);
+	ARRAY_DEFINE(tmp_offsets, uint32_t);
 
 	/* if cached_exists_buf[field] == cached_exists_value, it's cached.
 	   this allows us to avoid constantly clearing the whole buffer.
--- a/src/lib-index/mail-cache-transaction.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-index/mail-cache-transaction.c	Wed Jun 28 16:10:25 2006 +0300
@@ -28,17 +28,19 @@
 	uint32_t cache_file_seq;
 
 	buffer_t *cache_data;
-	array_t ARRAY_DEFINE(cache_data_seq, uint32_t);
+	ARRAY_DEFINE(cache_data_seq, uint32_t);
 	uint32_t prev_seq;
 	size_t prev_pos;
 
-        array_t ARRAY_DEFINE(reservations, struct mail_cache_reservation);
+        ARRAY_DEFINE(reservations, struct mail_cache_reservation);
 	uint32_t reserved_space_offset, reserved_space;
 	uint32_t last_grow_size;
 
 	unsigned int changes:1;
 };
 
+ARRAY_DEFINE_TYPE(uint32_t, uint32_t);
+
 static int mail_cache_link_unlocked(struct mail_cache *cache,
 				    uint32_t old_offset, uint32_t new_offset);
 
@@ -255,7 +257,7 @@
 		/* grow reservation. it's probably the last one in the buffer,
 		   but it's not guarateed because we might have used holes
 		   as well */
-		reservations = array_get_modifyable(&ctx->reservations, &count);
+		reservations = array_get_modifiable(&ctx->reservations, &count);
 
 		do {
 			i_assert(count > 0);
@@ -537,7 +539,7 @@
 
 	if (ctx->prev_seq != 0) {
 		/* fix record size */
-		data = buffer_get_modifyable_data(ctx->cache_data, &size);
+		data = buffer_get_modifiable_data(ctx->cache_data, &size);
 		rec = PTR_OFFSET(data, ctx->prev_pos);
 		rec->size = size - ctx->prev_pos;
 		i_assert(rec->size != 0);
@@ -803,9 +805,8 @@
 	return 0;
 }
 
-static bool find_offset(array_t *array, uint32_t offset)
+static bool find_offset(ARRAY_TYPE(uint32_t) *array, uint32_t offset)
 {
-	ARRAY_SET_TYPE(array, uint32_t);
 	const uint32_t *offsets;
 	unsigned int i, count;
 
@@ -820,7 +821,7 @@
 int mail_cache_delete(struct mail_cache *cache, uint32_t offset)
 {
 	const struct mail_cache_record *cache_rec;
-	array_t ARRAY_DEFINE(tmp_offsets, uint32_t);
+	ARRAY_TYPE(uint32_t) tmp_offsets;
 
 	i_assert(cache->locked);
 
--- a/src/lib-index/mail-index-private.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-index/mail-index-private.h	Wed Jun 28 16:10:25 2006 +0300
@@ -39,6 +39,8 @@
 				      const void *new_data, void **context);
 typedef void mail_index_sync_lost_handler_t(struct mail_index *index);
 
+ARRAY_DEFINE_TYPE(seq_array, uint32_t);
+
 #define MAIL_INDEX_HEADER_SIZE_ALIGN(size) \
 	(((size) + 7) & ~7)
 
@@ -106,8 +108,8 @@
 	unsigned int records_count;
 
 	pool_t extension_pool;
-	array_t ARRAY_DEFINE(extensions, struct mail_index_ext);
-	array_t ARRAY_DEFINE(ext_id_map, uint32_t); /* index -> file */
+	ARRAY_DEFINE(extensions, struct mail_index_ext);
+	ARRAY_DEFINE(ext_id_map, uint32_t); /* index -> file */
 
 	void *mmap_base;
 	size_t mmap_size, mmap_used_size;
@@ -115,7 +117,7 @@
 	buffer_t *buffer;
 	buffer_t *hdr_copy_buf;
 
-	array_t ARRAY_DEFINE(keyword_idx_map, unsigned int); /* file -> index */
+	ARRAY_DEFINE(keyword_idx_map, unsigned int); /* file -> index */
 
 	/* If write_to_disk=TRUE and write_atomic=FALSE, these sequences
 	   specify the range that needs to be written. Header should always
@@ -136,10 +138,9 @@
 	gid_t gid;
 
 	pool_t extension_pool;
-	array_t ARRAY_DEFINE(extensions, struct mail_index_registered_ext);
+	ARRAY_DEFINE(extensions, struct mail_index_registered_ext);
 
-	array_t ARRAY_DEFINE(sync_lost_handlers,
-			     mail_index_sync_lost_handler_t *);
+	ARRAY_DEFINE(sync_lost_handlers, mail_index_sync_lost_handler_t *);
 
 	char *filepath;
 	int fd;
@@ -160,12 +161,15 @@
 	uoff_t sync_log_file_offset;
 
 	pool_t keywords_pool;
-	array_t ARRAY_DEFINE(keywords, const char *);
+	ARRAY_TYPE(keywords) keywords;
 	struct hash_table *keywords_hash; /* name -> idx */
 
 	uint32_t keywords_ext_id;
 	unsigned int last_grow_count;
 
+	/* Module-specific contexts. See mail_index_module_id. */
+	ARRAY_DEFINE(module_contexts, void);
+
 	char *error;
 	unsigned int nodiskspace:1;
 	unsigned int index_lock_timeout:1;
--- a/src/lib-index/mail-index-sync-ext.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-index/mail-index-sync-ext.c	Wed Jun 28 16:10:25 2006 +0300
@@ -34,7 +34,7 @@
 	rext = array_get(&ctx->view->index->extensions, &rext_count);
 	ext = array_get(&ctx->view->map->extensions, &ext_count);
 	id_map = array_get(&ctx->view->map->ext_id_map, &id_map_count);
-	contexts = array_get_modifyable(&ctx->extra_contexts, &context_count);
+	contexts = array_get_modifiable(&ctx->extra_contexts, &context_count);
 
 	i_assert(id_map_count <= rext_count);
 
@@ -91,7 +91,7 @@
 	}
 
 	/* fill the context array with NULLs */
-	(void)array_idx_modifyable(&ctx->extra_contexts, count - 1);
+	(void)array_idx_modifiable(&ctx->extra_contexts, count - 1);
 	ctx->expunge_handlers_set = FALSE;
 }
 
@@ -115,7 +115,7 @@
 
 	/* extra_contexts[] is ordered by map->extensions. */
 	extra_contexts =
-		array_get_modifyable(&ctx->extra_contexts, &context_count);
+		array_get_modifiable(&ctx->extra_contexts, &context_count);
 	i_assert(count <= context_count);
 
 	for (i = 0; i < count; i++) {
@@ -141,7 +141,7 @@
 		MAIL_INDEX_HEADER_SIZE_ALIGN(sizeof(*ext_hdr) +
 					     strlen(ext->name));
 
-	hdr_base = buffer_get_modifyable_data(map->hdr_copy_buf, NULL);
+	hdr_base = buffer_get_modifiable_data(map->hdr_copy_buf, NULL);
 	ext_hdr = PTR_OFFSET(hdr_base, offset);
 	i_assert(memcmp((char *)(ext_hdr + 1),
 			ext->name, strlen(ext->name)) == 0);
@@ -167,7 +167,7 @@
 	const void *src;
 
 	t_push();
-	ext = array_get_modifyable(&map->extensions, &count);
+	ext = array_get_modifiable(&map->extensions, &count);
 
 	/* @UNSAFE */
 	old_offsets = t_new(uint16_t, count);
@@ -256,7 +256,7 @@
 		buffer_append_zero(new_map->buffer, space);
 	}
 
-	new_map->records = buffer_get_modifyable_data(new_map->buffer, NULL);
+	new_map->records = buffer_get_modifiable_data(new_map->buffer, NULL);
 	new_map->records_count = old_records_count;
 	i_assert(new_map->records_count == new_map->hdr.messages_count);
 
@@ -280,7 +280,7 @@
 	uint32_t old_size, new_size, old_record_size;
 	bool modified = FALSE;
 
-	ext = array_idx_modifyable(&map->extensions, ext_id);
+	ext = array_idx_modifiable(&map->extensions, ext_id);
 
 	old_size = MAIL_INDEX_HEADER_SIZE_ALIGN(ext->hdr_size);
 	new_size = MAIL_INDEX_HEADER_SIZE_ALIGN(u->hdr_size);
@@ -324,7 +324,7 @@
 		unsigned i, count = array_count(&map->extensions);
 		ssize_t diff = (ssize_t)new_size - (ssize_t)old_size;
 
-		ext = array_idx_modifyable(&map->extensions, 0);
+		ext = array_idx_modifiable(&map->extensions, 0);
 		for (i = ext_id + 1; i < count; i++)
 			ext[i].hdr_offset += diff;
 	}
@@ -468,7 +468,7 @@
 		mail_index_sync_replace_map(ctx, map);
 	}
 
-	ext = array_idx_modifyable(&map->extensions, ctx->cur_ext_id);
+	ext = array_idx_modifiable(&map->extensions, ctx->cur_ext_id);
 	ext->reset_id = u->new_reset_id;
 
 	memset(buffer_get_space_unsafe(map->hdr_copy_buf, ext->hdr_offset,
@@ -543,7 +543,7 @@
 	   current synchronization type (index/view) */
 	if ((rext->sync_handler.type & ctx->type) != 0) {
 		void **extra_context =
-			array_idx_modifyable(&ctx->extra_contexts,
+			array_idx_modifiable(&ctx->extra_contexts,
 					     ctx->cur_ext_id);
 		ret = rext->sync_handler.callback(ctx, seq, old_data, u + 1,
 						  extra_context);
--- a/src/lib-index/mail-index-sync-private.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-index/mail-index-sync-private.h	Wed Jun 28 16:10:25 2006 +0300
@@ -3,6 +3,11 @@
 
 #include "mail-transaction-log.h"
 
+struct uid_range {
+	uint32_t uid1, uid2;
+};
+ARRAY_DEFINE_TYPE(uid_range, struct uid_range);
+
 struct mail_index_sync_ctx {
 	struct mail_index *index;
 	struct mail_index_view *view;
@@ -11,7 +16,7 @@
 	const struct mail_transaction_header *hdr;
 	const void *data;
 
-	array_t ARRAY_DEFINE(sync_list, struct mail_index_sync_list);
+	ARRAY_DEFINE(sync_list, struct mail_index_sync_list);
 	uint32_t next_uid;
 
 	uint32_t append_uid_first, append_uid_last;
@@ -24,7 +29,7 @@
 };
 
 struct mail_index_sync_list {
-	const array_t *ARRAY_DEFINE_PTR(array, struct uid_range);
+	const ARRAY_TYPE(uid_range) *array;
 	unsigned int idx;
 	unsigned int keyword_idx:31;
 	unsigned int keyword_remove:1;
@@ -40,10 +45,8 @@
 	struct mail_index_view *view;
 	uint32_t cur_ext_id;
 
-	array_t ARRAY_DEFINE(expunge_handlers,
-			     struct mail_index_expunge_handler);
-
-	array_t ARRAY_DEFINE(extra_contexts, void *);
+	ARRAY_DEFINE(expunge_handlers, struct mail_index_expunge_handler);
+	ARRAY_DEFINE(extra_contexts, void *);
 
         enum mail_index_sync_handler_type type;
 
--- a/src/lib-index/mail-index-sync-update.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-index/mail-index-sync-update.c	Wed Jun 28 16:10:25 2006 +0300
@@ -213,7 +213,7 @@
 	if (map->buffer != NULL) {
 		buffer_set_used_size(map->buffer, map->records_count *
 				     map->hdr.record_size);
-		map->records = buffer_get_modifyable_data(map->buffer, NULL);
+		map->records = buffer_get_modifiable_data(map->buffer, NULL);
 	}
 	return 1;
 }
@@ -247,7 +247,7 @@
 			 buffer_get_used_size(map->buffer));
 		dest = buffer_append_space_unsafe(map->buffer,
 						  map->hdr.record_size);
-		map->records = buffer_get_modifyable_data(map->buffer, NULL);
+		map->records = buffer_get_modifiable_data(map->buffer, NULL);
 	} else {
 		i_assert((map->records_count+1) * map->hdr.record_size <=
 			 map->mmap_size);
--- a/src/lib-index/mail-index-sync.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-index/mail-index-sync.c	Wed Jun 28 16:10:25 2006 +0300
@@ -12,10 +12,6 @@
 
 #include <stdlib.h>
 
-struct uid_range {
-	uint32_t uid1, uid2;
-};
-
 static void mail_index_sync_add_expunge(struct mail_index_sync_ctx *ctx)
 {
 	const struct mail_transaction_expunge *e = ctx->data;
@@ -224,18 +220,18 @@
 
 	if (array_is_created(&ctx->trans->expunges)) {
 		synclist = array_append_space(&ctx->sync_list);
-		synclist->array = &ctx->trans->expunges;
+		synclist->array = (void *)&ctx->trans->expunges;
 	}
 
 	if (array_is_created(&ctx->trans->updates)) {
 		synclist = array_append_space(&ctx->sync_list);
-		synclist->array = &ctx->trans->updates;
+		synclist->array = (void *)&ctx->trans->updates;
 	}
 
 	/* we must return resets before keyword additions or they get lost */
 	if (array_is_created(&ctx->trans->keyword_resets)) {
 		synclist = array_append_space(&ctx->sync_list);
-		synclist->array = &ctx->trans->keyword_resets;
+		synclist->array = (void *)&ctx->trans->keyword_resets;
 	}
 
 	keyword_updates = keyword_count == 0 ? NULL :
@@ -243,12 +239,13 @@
 	for (i = 0; i < keyword_count; i++) {
 		if (array_is_created(&keyword_updates[i].add_seq)) {
 			synclist = array_append_space(&ctx->sync_list);
-			synclist->array = &keyword_updates[i].add_seq;
+			synclist->array = (void *)&keyword_updates[i].add_seq;
 			synclist->keyword_idx = i;
 		}
 		if (array_is_created(&keyword_updates[i].remove_seq)) {
 			synclist = array_append_space(&ctx->sync_list);
-			synclist->array = &keyword_updates[i].remove_seq;
+			synclist->array =
+				(void *)&keyword_updates[i].remove_seq;
 			synclist->keyword_idx = i;
 			synclist->keyword_remove = TRUE;
 		}
@@ -536,7 +533,7 @@
 	/* FIXME: replace with a priority queue so we don't have to go
 	   through the whole list constantly. and remember to make sure that
 	   keyword resets are sent before adds! */
-	sync_list = array_get_modifyable(&ctx->sync_list, &count);
+	sync_list = array_get_modifiable(&ctx->sync_list, &count);
 	for (i = 0; i < count; i++) {
 		if (!array_is_created(sync_list[i].array) ||
 		    sync_list[i].idx == array_count(sync_list[i].array))
@@ -570,13 +567,13 @@
 		uid_range = array_idx(sync_list[i].array, sync_list[i].idx);
 	}
 
-	if (sync_list[i].array == &ctx->trans->expunges) {
+	if (sync_list[i].array == (void *)&ctx->trans->expunges) {
 		mail_index_sync_get_expunge(sync_rec,
 			(const struct mail_transaction_expunge *)uid_range);
-	} else if (sync_list[i].array == &ctx->trans->updates) {
+	} else if (sync_list[i].array == (void *)&ctx->trans->updates) {
 		mail_index_sync_get_update(sync_rec,
 			(const struct mail_transaction_flag_update *)uid_range);
-	} else if (sync_list[i].array == &ctx->trans->keyword_resets) {
+	} else if (sync_list[i].array == (void *)&ctx->trans->keyword_resets) {
 		mail_index_sync_get_keyword_reset(sync_rec, uid_range);
 	} else {
 		mail_index_sync_get_keyword_update(sync_rec, uid_range,
@@ -613,7 +610,7 @@
 
 	ctx->next_uid = 0;
 
-	sync_list = array_get_modifyable(&ctx->sync_list, &count);
+	sync_list = array_get_modifiable(&ctx->sync_list, &count);
 	for (i = 0; i < count; i++)
 		sync_list[i].idx = 0;
 }
@@ -699,9 +696,8 @@
 }
 
 bool mail_index_sync_keywords_apply(const struct mail_index_sync_rec *sync_rec,
-				    array_t *keywords)
+				    ARRAY_TYPE(keyword_indexes) *keywords)
 {
-	ARRAY_SET_TYPE(keywords, unsigned int);
 	const unsigned int *keyword_indexes;
 	unsigned int idx = sync_rec->keyword_idx;
 	unsigned int i, count;
--- a/src/lib-index/mail-index-transaction-private.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-index/mail-index-transaction-private.h	Wed Jun 28 16:10:25 2006 +0300
@@ -1,22 +1,23 @@
 #ifndef __MAIL_INDEX_TRANSACTION_PRIVATE_H
 #define __MAIL_INDEX_TRANSACTION_PRIVATE_H
 
+#include "seq-range-array.h"
 #include "mail-transaction-log.h"
 
 struct mail_index_transaction_keyword_update {
-	array_t ARRAY_DEFINE(add_seq, struct seq_range);
-	array_t ARRAY_DEFINE(remove_seq, struct seq_range);
+	ARRAY_TYPE(seq_range) add_seq;
+	ARRAY_TYPE(seq_range) remove_seq;
 };
 
 struct mail_index_transaction {
 	int refcount;
 	struct mail_index_view *view;
 
-        array_t ARRAY_DEFINE(appends, struct mail_index_record);
+        ARRAY_DEFINE(appends, struct mail_index_record);
 	uint32_t first_new_seq, last_new_seq;
 
-	array_t ARRAY_DEFINE(expunges, struct mail_transaction_expunge);
-	array_t ARRAY_DEFINE(updates, struct mail_transaction_flag_update);
+	ARRAY_TYPE(seq_range) expunges;
+	ARRAY_DEFINE(updates, struct mail_transaction_flag_update);
 	size_t last_update_idx;
 
 	unsigned char pre_hdr_change[sizeof(struct mail_index_header)];
@@ -24,13 +25,13 @@
 	unsigned char post_hdr_change[sizeof(struct mail_index_header)];
 	unsigned char post_hdr_mask[sizeof(struct mail_index_header)];
 
-	array_t ARRAY_DEFINE(ext_rec_updates, array_t);
-	array_t ARRAY_DEFINE(ext_resizes, struct mail_transaction_ext_intro);
-	array_t ARRAY_DEFINE(ext_resets, uint32_t);
+	ARRAY_DEFINE(ext_rec_updates, ARRAY_TYPE(seq_array));
+	ARRAY_DEFINE(ext_resizes, struct mail_transaction_ext_intro);
+	ARRAY_DEFINE(ext_resets, uint32_t);
 
-	array_t ARRAY_DEFINE(keyword_updates,
-			     struct mail_index_transaction_keyword_update);
-	array_t ARRAY_DEFINE(keyword_resets, struct seq_range);
+	ARRAY_DEFINE(keyword_updates,
+		     struct mail_index_transaction_keyword_update);
+	ARRAY_TYPE(seq_range) keyword_resets;
 
         struct mail_cache_transaction_ctx *cache_trans_ctx;
 
@@ -49,7 +50,7 @@
 void mail_index_transaction_ref(struct mail_index_transaction *t);
 void mail_index_transaction_unref(struct mail_index_transaction **t);
 
-bool mail_index_seq_array_lookup(const array_t *buffer, uint32_t seq,
-				 unsigned int *idx_r);
+bool mail_index_seq_array_lookup(const ARRAY_TYPE(seq_array) *array,
+				 uint32_t seq, unsigned int *idx_r);
 
 #endif
--- a/src/lib-index/mail-index-transaction-view.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-index/mail-index-transaction-view.c	Wed Jun 28 16:10:25 2006 +0300
@@ -145,8 +145,7 @@
 {
 	struct mail_index_view_transaction *tview =
 		(struct mail_index_view_transaction *)view;
-	const array_t *ext_buf;
-	ARRAY_SET_TYPE(ext_buf, void *);
+	const ARRAY_TYPE(seq_array) *ext_buf;
 	const void *data;
 	unsigned int idx;
 
--- a/src/lib-index/mail-index-transaction.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-index/mail-index-transaction.c	Wed Jun 28 16:10:25 2006 +0300
@@ -43,11 +43,11 @@
 
 static void mail_index_transaction_free(struct mail_index_transaction *t)
 {
-	array_t *recs;
+	ARRAY_TYPE(seq_array) *recs;
 	unsigned i, count;
 
 	if (array_is_created(&t->ext_rec_updates)) {
-		recs = array_get_modifyable(&t->ext_rec_updates, &count);
+		recs = array_get_modifiable(&t->ext_rec_updates, &count);
 
 		for (i = 0; i < count; i++) {
 			if (array_is_created(&recs[i]))
@@ -59,7 +59,7 @@
 	if (array_is_created(&t->keyword_updates)) {
 		struct mail_index_transaction_keyword_update *u;
 
-		u = array_get_modifyable(&t->keyword_updates, &count);
+		u = array_get_modifiable(&t->keyword_updates, &count);
 
 		for (i = 0; i < count; i++) {
 			if (array_is_created(&u[i].add_seq))
@@ -102,10 +102,9 @@
 		mail_index_transaction_free(t);
 }
 
-bool mail_index_seq_array_lookup(const array_t *array, uint32_t seq,
-				 unsigned int *idx_r)
+bool mail_index_seq_array_lookup(const ARRAY_TYPE(seq_array) *array,
+				 uint32_t seq, unsigned int *idx_r)
 {
-        ARRAY_SET_TYPE(array, uint32_t);
 	unsigned int idx, left_idx, right_idx, count;
 	const uint32_t *seq_p;
 
@@ -140,24 +139,22 @@
 	return FALSE;
 }
 
-static bool mail_index_seq_array_add(array_t *array, uint32_t seq,
+static bool mail_index_seq_array_add(ARRAY_TYPE(seq_array) *array, uint32_t seq,
 				     const void *record, size_t record_size,
 				     void *old_record)
 {
-        ARRAY_SET_TYPE(array, void *);
 	void *p;
 	unsigned int idx;
 
 	if (!array_is_created(array)) {
-		array_create(array, default_pool,
-			     sizeof(seq) + record_size,
+		array_create(array, default_pool, sizeof(seq) + record_size,
 			     1024 / (sizeof(seq) + record_size));
 	}
-	i_assert(array->element_size == sizeof(seq) + record_size);
+	i_assert(array->arr.element_size == sizeof(seq) + record_size);
 
 	if (mail_index_seq_array_lookup(array, seq, &idx)) {
 		/* already there, update */
-		p = array_idx_modifyable(array, idx);
+		p = array_idx_modifiable(array, idx);
 		if (old_record != NULL) {
 			/* save the old record before overwriting it */
 			memcpy(old_record, PTR_OFFSET(p, sizeof(seq)),
@@ -176,9 +173,8 @@
 
 static void
 mail_index_buffer_convert_to_uids(struct mail_index_transaction *t,
-				  array_t *array, bool range)
+				  ARRAY_TYPE(seq_array) *array, bool range)
 {
-        ARRAY_SET_TYPE(array, uint32_t);
         struct mail_index_view *view = t->view;
 	const struct mail_index_record *rec;
 	uint32_t *seq;
@@ -190,7 +186,7 @@
 	count = array_count(array);
 	range_count = range ? 1 : 0;
 	for (i = 0; i < count; i++) {
-		seq = array_idx_modifyable(array, i);
+		seq = array_idx_modifiable(array, i);
 
 		for (j = 0; j <= range_count; j++, seq++) {
 			i_assert(*seq > 0);
@@ -215,25 +211,6 @@
 	}
 }
 
-static void arrays_convert_to_uids(struct mail_index_transaction *t,
-				   array_t *array, bool range)
-{
-	ARRAY_SET_TYPE(array, array_t);
-	array_t *updates;
-	unsigned int i, count;
-
-	if (!array_is_created(array))
-		return;
-
-	updates = array_get_modifyable(array, &count);
-	for (i = 0; i < count; i++) {
-		if (array_is_created(&updates[i])) {
-			mail_index_buffer_convert_to_uids(t, &updates[i],
-							  range);
-		}
-	}
-}
-
 static void keyword_updates_convert_to_uids(struct mail_index_transaction *t)
 {
         struct mail_index_transaction_keyword_update *updates;
@@ -242,15 +219,15 @@
 	if (!array_is_created(&t->keyword_updates))
 		return;
 
-	updates = array_get_modifyable(&t->keyword_updates, &count);
+	updates = array_get_modifiable(&t->keyword_updates, &count);
 	for (i = 0; i < count; i++) {
 		if (array_is_created(&updates[i].add_seq)) {
 			mail_index_buffer_convert_to_uids(t,
-				&updates[i].add_seq, TRUE);
+				(void *)&updates[i].add_seq, TRUE);
 		}
 		if (array_is_created(&updates[i].remove_seq)) {
 			mail_index_buffer_convert_to_uids(t,
-				&updates[i].remove_seq, TRUE);
+				(void *)&updates[i].remove_seq, TRUE);
 		}
 	}
 }
@@ -258,15 +235,27 @@
 static int
 mail_index_transaction_convert_to_uids(struct mail_index_transaction *t)
 {
+	ARRAY_TYPE(seq_array) *updates;
+	unsigned int i, count;
+
 	if (mail_index_view_lock(t->view) < 0)
 		return -1;
 
-	arrays_convert_to_uids(t, &t->ext_rec_updates, FALSE);
+	if (array_is_created(&t->ext_rec_updates)) {
+		updates = array_get_modifiable(&t->ext_rec_updates, &count);
+		for (i = 0; i < count; i++) {
+			if (!array_is_created(&updates[i]))
+				continue;
+			mail_index_buffer_convert_to_uids(t, &updates[i],
+							  FALSE);
+		}
+	}
+
         keyword_updates_convert_to_uids(t);
 
-	mail_index_buffer_convert_to_uids(t, &t->expunges, TRUE);
-	mail_index_buffer_convert_to_uids(t, &t->updates, TRUE);
-	mail_index_buffer_convert_to_uids(t, &t->keyword_resets, TRUE);
+	mail_index_buffer_convert_to_uids(t, (void *)&t->expunges, TRUE);
+	mail_index_buffer_convert_to_uids(t, (void *)&t->updates, TRUE);
+	mail_index_buffer_convert_to_uids(t, (void *)&t->keyword_resets, TRUE);
 	return 0;
 }
 
@@ -288,12 +277,12 @@
 {
 	struct mail_index_record *recs, *sorted_recs;
 	struct uid_map *new_uid_map;
-	array_t *ext_rec_arrays;
+	ARRAY_TYPE(seq_array) *ext_rec_arrays;
 	uint32_t *old_to_new_map;
 	unsigned int i, j, count, ext_rec_array_count;
 
 	/* first make a copy of the UIDs and map them to sequences */
-	recs = array_get_modifyable(&t->appends, &count);
+	recs = array_get_modifiable(&t->appends, &count);
 	new_uid_map = i_new(struct uid_map, count);
 	for (i = 0; i < count; i++) {
 		new_uid_map[i].idx = i;
@@ -311,17 +300,16 @@
 	sorted_recs = i_new(struct mail_index_record, count);
 	for (i = 0; i < count; i++)
 		sorted_recs[i] = recs[new_uid_map[i].idx];
-	buffer_write(t->appends.buffer, 0, sorted_recs,
+	buffer_write(t->appends.arr.buffer, 0, sorted_recs,
 		     sizeof(*sorted_recs) * count);
 	i_free(sorted_recs);
 
 	/* fix the order in extensions */
-	ext_rec_arrays = array_get_modifyable(&t->ext_rec_updates,
+	ext_rec_arrays = array_get_modifiable(&t->ext_rec_updates,
 					      &ext_rec_array_count);
 	for (j = 0; j < ext_rec_array_count; j++) {
-		array_t *old_array = &ext_rec_arrays[j];
-		ARRAY_SET_TYPE(old_array, void);
-		array_t new_array;
+		ARRAY_TYPE(seq_array) *old_array = &ext_rec_arrays[j];
+		ARRAY_TYPE(seq_array) new_array;
 		unsigned int ext_count;
 		const uint32_t *ext_rec;
 		uint32_t seq;
@@ -331,7 +319,7 @@
 
 		ext_count = array_count(old_array);
 		array_create(&new_array, default_pool,
-			     old_array->element_size, ext_count);
+			     old_array->arr.element_size, ext_count);
 		for (i = 0; i < ext_count; i++) {
 			ext_rec = array_idx(old_array, i);
 
@@ -339,7 +327,7 @@
 				(t->first_new_seq +
 				 old_to_new_map[*ext_rec - t->first_new_seq]);
 			mail_index_seq_array_add(&new_array, seq, ext_rec+1,
-						 old_array->element_size -
+						 old_array->arr.element_size -
 						 sizeof(*ext_rec), NULL);
 		}
 		array_free(old_array);
@@ -399,7 +387,7 @@
 {
 	i_assert(seq >= t->first_new_seq && seq <= t->last_new_seq);
 
-	return array_idx_modifyable(&t->appends, seq - t->first_new_seq);
+	return array_idx_modifiable(&t->appends, seq - t->first_new_seq);
 }
 
 void mail_index_append(struct mail_index_transaction *t, uint32_t uid,
@@ -446,7 +434,7 @@
 	if (!array_is_created(&t->appends))
 		return;
 
-	recs = array_get_modifyable(&t->appends, &count);
+	recs = array_get_modifiable(&t->appends, &count);
 
 	/* find the first mail with uid = 0 */
 	for (i = 0; i < count; i++) {
@@ -481,7 +469,7 @@
 	unsigned int count;
 	uint32_t idx, move;
 
-	updates = array_get_modifyable(&t->updates, &count);
+	updates = array_get_modifiable(&t->updates, &count);
 
 	i_assert(left_idx <= right_idx && right_idx <= count);
 
@@ -526,7 +514,7 @@
 			i_assert(updates[idx].uid1 <= updates[idx].uid2);
 
 			array_insert(&t->updates, idx, &tmp_update, 1);
-			updates = array_get_modifyable(&t->updates, &count);
+			updates = array_get_modifiable(&t->updates, &count);
 			idx += move;
 		} else if (u.uid1 < updates[idx].uid1) {
 			updates[idx].uid1 = u.uid1;
@@ -544,7 +532,7 @@
 			i_assert(updates[idx].uid1 <= updates[idx].uid2);
 
 			array_insert(&t->updates, idx, &tmp_update, 1);
-			updates = array_get_modifyable(&t->updates, &count);
+			updates = array_get_modifiable(&t->updates, &count);
 		}
 
 		updates[idx].add_flags =
@@ -641,7 +629,7 @@
 		return;
 	}
 
-	last_update = array_get_modifyable(&t->updates, &count);
+	last_update = array_get_modifiable(&t->updates, &count);
 	if (t->last_update_idx < count) {
 		/* fast path - hopefully we're updating the next message,
 		   or a message that is to be appended as last update */
@@ -763,9 +751,9 @@
 	if (array_is_created(&t->ext_rec_updates) &&
 	    ext_id < array_count(&t->ext_rec_updates)) {
 		/* if extension records have been updated, clear them */
-		array_t *array;
+		ARRAY_TYPE(seq_array) *array;
 
-		array = array_idx_modifyable(&t->ext_rec_updates, ext_id);
+		array = array_idx_modifiable(&t->ext_rec_updates, ext_id);
 		if (array_is_created(array))
 			array_clear(array);
 	}
@@ -791,7 +779,7 @@
         const struct mail_index_registered_ext *rext;
 	const struct mail_transaction_ext_intro *intro;
 	uint16_t record_size;
-	array_t *array;
+	ARRAY_TYPE(seq_array) *array;
 	unsigned int count;
 
 	i_assert(seq > 0 &&
@@ -817,9 +805,9 @@
 
 	if (!array_is_created(&t->ext_rec_updates)) {
 		ARRAY_CREATE(&t->ext_rec_updates, default_pool,
-			     array_t, ext_id + 2);
+			     ARRAY_TYPE(seq_array), ext_id + 2);
 	}
-	array = array_idx_modifyable(&t->ext_rec_updates, ext_id);
+	array = array_idx_modifiable(&t->ext_rec_updates, ext_id);
 
 	/* @UNSAFE */
 	if (!mail_index_seq_array_add(array, seq, data, record_size,
@@ -862,9 +850,9 @@
 
 struct mail_keywords *
 mail_index_keywords_create_from_indexes(struct mail_index_transaction *t,
-					const array_t *keyword_indexes)
+					const ARRAY_TYPE(keyword_indexes)
+						*keyword_indexes)
 {
-	ARRAY_SET_TYPE(keyword_indexes, unsigned int);
 	struct mail_keywords *k;
 	unsigned int count;
 
@@ -920,7 +908,7 @@
 	switch (modify_type) {
 	case MODIFY_ADD:
 		for (i = 0; i < keywords->count; i++) {
-			u = array_idx_modifyable(&t->keyword_updates,
+			u = array_idx_modifiable(&t->keyword_updates,
 						 keywords->idx[i]);
 			seq_range_array_add(&u->add_seq, 16, seq);
 			if (seq < t->first_new_seq)
@@ -929,7 +917,7 @@
 		break;
 	case MODIFY_REMOVE:
 		for (i = 0; i < keywords->count; i++) {
-			u = array_idx_modifyable(&t->keyword_updates,
+			u = array_idx_modifiable(&t->keyword_updates,
 						 keywords->idx[i]);
 			seq_range_array_remove(&u->add_seq, seq);
 			if (seq < t->first_new_seq)
@@ -939,7 +927,7 @@
 	case MODIFY_REPLACE:
 		/* Remove sequence from all add/remove arrays */
 		if (array_is_created(&t->keyword_updates)) {
-			u = array_get_modifyable(&t->keyword_updates,
+			u = array_get_modifiable(&t->keyword_updates,
 						 &ku_count);
 			for (i = 0; i < ku_count; i++) {
 				seq_range_array_remove(&u[i].add_seq, seq);
@@ -951,7 +939,7 @@
 		}
 		/* Add the wanted keyword back */
 		for (i = 0; i < keywords->count; i++) {
-			u = array_idx_modifyable(&t->keyword_updates,
+			u = array_idx_modifiable(&t->keyword_updates,
 						 keywords->idx[i]);
 			seq_range_array_add(&u->add_seq, 16, seq);
 		}
--- a/src/lib-index/mail-index-view-private.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-index/mail-index-view-private.h	Wed Jun 28 16:10:25 2006 +0300
@@ -3,6 +3,12 @@
 
 #include "mail-index-private.h"
 
+struct mail_index_view_log_sync_pos {
+	uint32_t log_file_seq;
+	uoff_t log_file_offset;
+};
+ARRAY_DEFINE_TYPE(view_log_sync_pos, struct mail_index_view_log_sync_pos);
+
 struct mail_index_view_methods {
 	void (*close)(struct mail_index_view *view);
 	uint32_t (*get_messages_count)(struct mail_index_view *view);
@@ -39,16 +45,16 @@
 	struct mail_index_map *sync_new_map;
 	/* All mappings where we have returned records. They need to be kept
 	   valid until view is synchronized. */
-	array_t ARRAY_DEFINE(map_refs, struct mail_index_map *);
+	ARRAY_DEFINE(map_refs, struct mail_index_map *);
 
 	struct mail_index_header hdr;
 
 	uint32_t log_file_seq;
 	uoff_t log_file_offset;
 	/* Transaction log offsets which we have already synced */
-	array_t ARRAY_DEFINE(syncs_done, struct mail_index_view_log_sync_pos);
+	ARRAY_TYPE(view_log_sync_pos) syncs_done;
 	/* Transaction log offsets which we don't want to return in view sync */
-	array_t ARRAY_DEFINE(syncs_hidden, struct mail_index_view_log_sync_pos);
+	ARRAY_TYPE(view_log_sync_pos) syncs_hidden;
 
 	int transactions;
 	unsigned int lock_id;
--- a/src/lib-index/mail-index-view-sync.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-index/mail-index-view-sync.c	Wed Jun 28 16:10:25 2006 +0300
@@ -12,7 +12,7 @@
 	struct mail_index_view *view;
 	enum mail_transaction_type visible_sync_mask;
 	struct mail_index_sync_map_ctx sync_map_ctx;
-	array_t ARRAY_DEFINE(expunges, struct mail_transaction_expunge);
+	ARRAY_TYPE(uid_range) expunges;
 
 	const struct mail_transaction_header *hdr;
 	const void *data;
@@ -23,26 +23,18 @@
 	unsigned int sync_map_update:1;
 };
 
-struct mail_index_view_log_sync_pos {
-	uint32_t log_file_seq;
-	uoff_t log_file_offset;
-};
-
 static void
-mail_transaction_log_sort_expunges(array_t *expunges,
-				   const struct mail_transaction_expunge *src,
-				   size_t src_size)
+mail_transaction_log_sort_expunges(ARRAY_TYPE(uid_range) *expunges,
+				   const struct uid_range *src, size_t src_size)
 {
-	ARRAY_SET_TYPE(expunges, struct mail_transaction_expunge);
-	const struct mail_transaction_expunge *src_end;
-	struct mail_transaction_expunge *dest;
-	struct mail_transaction_expunge new_exp;
+	const struct uid_range *src_end;
+	struct uid_range *dest, new_exp;
 	unsigned int first, i, dest_count;
 
 	i_assert(src_size % sizeof(*src) == 0);
 
 	/* @UNSAFE */
-	dest = array_get_modifyable(expunges, &dest_count);
+	dest = array_get_modifiable(expunges, &dest_count);
 	if (dest_count == 0) {
 		array_append(expunges, src, src_size / sizeof(*src));
 		return;
@@ -77,7 +69,7 @@
 			array_insert(expunges, i, &new_exp, 1);
 			i++; first++;
 
-			dest = array_get_modifyable(expunges, &dest_count);
+			dest = array_get_modifiable(expunges, &dest_count);
 		} else {
 			/* use next record */
 			dest[first] = new_exp;
@@ -87,7 +79,7 @@
 		if (i > first) {
 			array_delete(expunges, first, i - first);
 
-			dest = array_get_modifyable(expunges, &dest_count);
+			dest = array_get_modifiable(expunges, &dest_count);
 			i = first;
 		}
 	}
@@ -119,11 +111,11 @@
 }
 
 static int
-view_sync_get_expunges(struct mail_index_view *view, array_t *expunges_r)
+view_sync_get_expunges(struct mail_index_view *view,
+		       ARRAY_TYPE(uid_range) *expunges_r)
 {
-	ARRAY_SET_TYPE(expunges_r, struct mail_transaction_expunge);
 	const struct mail_transaction_header *hdr;
-	struct mail_transaction_expunge *src, *src_end, *dest;
+	struct uid_range *src, *src_end, *dest;
 	const void *data;
 	unsigned int count;
 	int ret;
@@ -131,8 +123,7 @@
 	if (view_sync_set_log_view_range(view, MAIL_TRANSACTION_EXPUNGE) < 0)
 		return -1;
 
-	ARRAY_CREATE(expunges_r, default_pool,
-		     struct mail_transaction_expunge, 64);
+	ARRAY_CREATE(expunges_r, default_pool, struct uid_range, 64);
 	while ((ret = mail_transaction_log_view_next(view->log_view,
 						     &hdr, &data, NULL)) > 0) {
 		i_assert((hdr->type & MAIL_TRANSACTION_EXPUNGE) != 0);
@@ -145,7 +136,7 @@
 	}
 
 	/* convert to sequences */
-	src = dest = array_get_modifyable(expunges_r, &count);
+	src = dest = array_get_modifiable(expunges_r, &count);
 	src_end = src + count;
 	for (; src != src_end; src++) {
 		ret = mail_index_lookup_uid_range(view, src->uid1,
@@ -204,7 +195,7 @@
 	struct mail_index_view_sync_ctx *ctx;
 	struct mail_index_map *map;
 	enum mail_transaction_type log_get_mask, visible_mask;
-	array_t expunges = { 0, 0 };
+	ARRAY_TYPE(uid_range) expunges = ARRAY_INIT;
 
 	/* We must sync flags as long as view is mmap()ed, as the flags may
 	   have already changed under us. */
@@ -317,9 +308,9 @@
 	return 0;
 }
 
-static bool view_sync_pos_find(array_t *sync_arr, uint32_t seq, uoff_t offset)
+static bool view_sync_pos_find(ARRAY_TYPE(view_log_sync_pos) *sync_arr,
+			       uint32_t seq, uoff_t offset)
 {
-	ARRAY_SET_TYPE(sync_arr, struct mail_index_view_log_sync_pos);
 	const struct mail_index_view_log_sync_pos *syncs;
 	unsigned int i, count;
 
@@ -524,7 +515,7 @@
 mail_index_view_sync_get_expunges(struct mail_index_view_sync_ctx *ctx,
 				  unsigned int *count_r)
 {
-	const struct mail_transaction_expunge *data;
+	const struct uid_range *data;
 
 	data = array_get(&ctx->expunges, count_r);
 	return (const uint32_t *)data;
@@ -532,9 +523,8 @@
 
 static void
 mail_index_view_sync_clean_log_syncs(struct mail_index_view_sync_ctx *ctx,
-				     array_t *sync_arr)
+				     ARRAY_TYPE(view_log_sync_pos) *sync_arr)
 {
-	ARRAY_SET_TYPE(sync_arr, struct mail_index_view_log_sync_pos);
 	struct mail_index_view *view = ctx->view;
 	const struct mail_index_view_log_sync_pos *syncs;
 	unsigned int i, count;
@@ -600,10 +590,9 @@
 	i_free(ctx);
 }
 
-static void log_sync_pos_add(array_t *sync_arr, uint32_t log_file_seq,
-			     uoff_t log_file_offset)
+static void log_sync_pos_add(ARRAY_TYPE(view_log_sync_pos) *sync_arr,
+			     uint32_t log_file_seq, uoff_t log_file_offset)
 {
-	ARRAY_SET_TYPE(sync_arr, struct mail_index_view_log_sync_pos);
 	struct mail_index_view_log_sync_pos *pos;
 
 	if (!array_is_created(sync_arr)) {
--- a/src/lib-index/mail-index-view.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-index/mail-index-view.c	Wed Jun 28 16:10:25 2006 +0300
@@ -162,7 +162,7 @@
 	if (!array_is_created(&view->map_refs))
 		return;
 
-	maps = array_get_modifyable(&view->map_refs, &count);
+	maps = array_get_modifiable(&view->map_refs, &count);
 	for (i = 0; i < count; i++)
 		mail_index_unmap(view->index, &maps[i]);
 
@@ -482,9 +482,8 @@
 }
 
 int mail_index_lookup_keywords(struct mail_index_view *view, uint32_t seq,
-			       array_t *keyword_idx)
+			       ARRAY_TYPE(keyword_indexes) *keyword_idx)
 {
-	ARRAY_SET_TYPE(keyword_idx, unsigned int);
 	struct mail_index_map *map;
 	const void *data;
 	const unsigned char *keyword_data;
--- a/src/lib-index/mail-index.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-index/mail-index.c	Wed Jun 28 16:10:25 2006 +0300
@@ -112,7 +112,7 @@
 {
 	struct mail_index_registered_ext *rext;
 
-	rext = array_idx_modifyable(&index->extensions, ext_id);
+	rext = array_idx_modifiable(&index->extensions, ext_id);
 	i_assert(rext->expunge_handler == NULL);
 
 	rext->expunge_handler = cb;
@@ -123,7 +123,7 @@
 {
 	struct mail_index_registered_ext *rext;
 
-	rext = array_idx_modifyable(&index->extensions, ext_id);
+	rext = array_idx_modifiable(&index->extensions, ext_id);
 	i_assert(rext->expunge_handler != NULL);
 
 	rext->expunge_handler = NULL;
@@ -135,7 +135,7 @@
 {
 	struct mail_index_registered_ext *rext;
 
-	rext = array_idx_modifyable(&index->extensions, ext_id);
+	rext = array_idx_modifiable(&index->extensions, ext_id);
 	i_assert(rext->sync_handler.callback == NULL);
 
 	rext->sync_handler.callback = cb;
@@ -147,7 +147,7 @@
 {
 	struct mail_index_registered_ext *rext;
 
-	rext = array_idx_modifyable(&index->extensions, ext_id);
+	rext = array_idx_modifiable(&index->extensions, ext_id);
 	i_assert(rext->sync_handler.callback != NULL);
 
 	rext->sync_handler.callback = NULL;
@@ -182,7 +182,7 @@
 	size_t size;
 
 	if (map->extension_pool == NULL) {
-		size = (sizeof(array_t) + BUFFER_APPROX_SIZE) * 2 +
+		size = (sizeof(map->extensions) + BUFFER_APPROX_SIZE) * 2 +
 			initial_count * (EXTENSION_NAME_APPROX_LEN +
 					 sizeof(struct mail_index_ext) +
 					 sizeof(uint32_t));
@@ -484,7 +484,7 @@
 	return 0;
 }
 
-const array_t *mail_index_get_keywords(struct mail_index *index)
+const ARRAY_TYPE(keywords) *mail_index_get_keywords(struct mail_index *index)
 {
 	/* Make sure all the keywords are in index->keywords. It's quick to do
 	   if nothing has changed. */
@@ -1163,7 +1163,7 @@
 		}
 	}
 
-	mem_map->records = buffer_get_modifyable_data(mem_map->buffer, NULL);
+	mem_map->records = buffer_get_modifiable_data(mem_map->buffer, NULL);
 	mem_map->records_count = map->records_count;
 
 	mem_map->hdr_copy_buf =
@@ -1177,7 +1177,7 @@
 				       map->hdr.base_header_size),
 		      map->hdr.header_size - map->hdr.base_header_size);
 
-	hdr = buffer_get_modifyable_data(mem_map->hdr_copy_buf, NULL);
+	hdr = buffer_get_modifiable_data(mem_map->hdr_copy_buf, NULL);
 	if (hdr->base_header_size < sizeof(*hdr))
 		hdr->base_header_size = sizeof(*hdr);
 	hdr->record_size = new_record_size;
@@ -1202,7 +1202,7 @@
 		array_append_array(&mem_map->ext_id_map, &map->ext_id_map);
 
 		/* fix the name pointers to use our own pool */
-		extensions = array_get_modifyable(&mem_map->extensions, &count);
+		extensions = array_get_modifiable(&mem_map->extensions, &count);
 		for (i = 0; i < count; i++) {
 			extensions[i].name = p_strdup(mem_map->extension_pool,
 						      extensions[i].name);
--- a/src/lib-index/mail-index.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-index/mail-index.h	Wed Jun 28 16:10:25 2006 +0300
@@ -142,6 +142,8 @@
 	enum mail_index_sync_type type;
 };
 
+ARRAY_DEFINE_TYPE(keyword_indexes, unsigned int);
+
 struct mail_index;
 struct mail_index_map;
 struct mail_index_view;
@@ -282,7 +284,7 @@
 			   const struct mail_index_record **rec_r);
 /* Note that returned keyword indexes aren't sorted. */
 int mail_index_lookup_keywords(struct mail_index_view *view, uint32_t seq,
-			       array_t *keyword_idx);
+			       ARRAY_TYPE(keyword_indexes) *keyword_idx);
 /* Returns the UID for given message. May be slightly faster than
    mail_index_lookup()->uid. */
 int mail_index_lookup_uid(struct mail_index_view *view, uint32_t seq,
@@ -325,7 +327,7 @@
 /* Return a pointer to array of NULL-terminated list of keywords. Note that
    the array contents (and thus pointers inside it) may change after calling
    mail_index_keywords_create() or mail_index_sync_begin(). */
-const array_t *mail_index_get_keywords(struct mail_index *index);
+const ARRAY_TYPE(keywords) *mail_index_get_keywords(struct mail_index *index);
 
 /* Create a keyword list structure. It's freed automatically at the end of
    the transaction. */
@@ -334,7 +336,8 @@
 			   const char *const keywords[]);
 struct mail_keywords *
 mail_index_keywords_create_from_indexes(struct mail_index_transaction *t,
-					const array_t *keyword_indexes);
+					const ARRAY_TYPE(keyword_indexes)
+						*keyword_indexes);
 /* Free the keywords. */
 void mail_index_keywords_free(struct mail_keywords **keywords);
 /* Update keywords for given message. */
@@ -363,7 +366,7 @@
 /* Apply changes in MAIL_INDEX_SYNC_TYPE_KEYWORD_* typed sync records to given
    keywords array. Returns TRUE If something was changed. */
 bool mail_index_sync_keywords_apply(const struct mail_index_sync_rec *sync_rec,
-				    array_t *keywords);
+				    ARRAY_TYPE(keyword_indexes) *keywords);
 
 /* register index extension. name is a unique identifier for the extension.
    returns unique identifier for the name. */
--- a/src/lib-index/mail-transaction-log-append.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-index/mail-transaction-log-append.c	Wed Jun 28 16:10:25 2006 +0300
@@ -152,7 +152,7 @@
 		intro = NULL;
 		count = 0;
 	} else {
-		intro = array_get_modifyable(&t->ext_resizes, &count);
+		intro = array_get_modifiable(&t->ext_resizes, &count);
 	}
 
 	buf = buffer_create_dynamic(pool_datastack_create(), 128);
@@ -203,7 +203,7 @@
 	unsigned int update_count, resize_count, reset_count, ext_count;
 	uint32_t ext_id;
 	const uint32_t *reset;
-	const array_t *update;
+	const ARRAY_TYPE(seq_array) *update;
 	buffer_t *buf;
 
 	if (!array_is_created(&t->ext_rec_updates)) {
@@ -259,7 +259,7 @@
 static int log_append_ext_rec_updates(struct mail_transaction_log_file *file,
 				      struct mail_index_transaction *t)
 {
-	array_t *updates;
+	ARRAY_TYPE(seq_array) *updates;
 	const uint32_t *reset;
 	unsigned int ext_id, count, reset_count;
 	uint32_t reset_id;
@@ -268,14 +268,14 @@
 		updates = NULL;
 		count = 0;
 	} else {
-		updates = array_get_modifyable(&t->ext_rec_updates, &count);
+		updates = array_get_modifiable(&t->ext_rec_updates, &count);
 	}
 
 	if (!array_is_created(&t->ext_resets)) {
 		reset = NULL;
 		reset_count = 0;
 	} else {
-		reset = array_get_modifyable(&t->ext_resets, &reset_count);
+		reset = array_get_modifiable(&t->ext_resets, &reset_count);
 	}
 
 	for (ext_id = 0; ext_id < count; ext_id++) {
@@ -287,7 +287,7 @@
 		if (log_append_ext_intro(file, t, ext_id, reset_id) < 0)
 			return -1;
 
-		if (log_append_buffer(file, updates[ext_id].buffer, NULL,
+		if (log_append_buffer(file, updates[ext_id].arr.buffer, NULL,
 				      MAIL_TRANSACTION_EXT_REC_UPDATE,
 				      t->external) < 0)
 			return -1;
@@ -332,22 +332,22 @@
 
 	hdr_buf = buffer_create_dynamic(pool_datastack_create(), 64);
 
-	keywords = array_get_modifyable(&t->view->index->keywords,
+	keywords = array_get_modifiable(&t->view->index->keywords,
 					&keywords_count);
-	updates = array_get_modifyable(&t->keyword_updates, &count);
+	updates = array_get_modifiable(&t->keyword_updates, &count);
 	i_assert(count <= keywords_count);
 
 	for (i = 0; i < count; i++) {
 		if (array_is_created(&updates[i].add_seq)) {
 			if (log_append_keyword_update(file, t, hdr_buf,
 					MODIFY_ADD, keywords[i],
-					updates[i].add_seq.buffer) < 0)
+					updates[i].add_seq.arr.buffer) < 0)
 				return -1;
 		}
 		if (array_is_created(&updates[i].remove_seq)) {
 			if (log_append_keyword_update(file, t, hdr_buf,
 					MODIFY_REMOVE, keywords[i],
-					updates[i].remove_seq.buffer) < 0)
+					updates[i].remove_seq.arr.buffer) < 0)
 				return -1;
 		}
 	}
@@ -454,7 +454,7 @@
 			mail_index_view_add_hidden_transaction(view,
 				file->hdr.file_seq, file->sync_offset);
 		}
-		ret = log_append_buffer(file, t->appends.buffer, NULL,
+		ret = log_append_buffer(file, t->appends.arr.buffer, NULL,
 					MAIL_TRANSACTION_APPEND, t->external);
 	}
 	if (array_is_created(&t->updates) && ret == 0) {
@@ -462,7 +462,7 @@
 			mail_index_view_add_hidden_transaction(view,
 				file->hdr.file_seq, file->sync_offset);
 		}
-		ret = log_append_buffer(file, t->updates.buffer, NULL,
+		ret = log_append_buffer(file, t->updates.arr.buffer, NULL,
 					MAIL_TRANSACTION_FLAG_UPDATE,
 					t->external);
 	}
@@ -476,8 +476,8 @@
 			mail_index_view_add_hidden_transaction(view,
 				file->hdr.file_seq, file->sync_offset);
 		}
-		ret = log_append_buffer(file, t->keyword_resets.buffer, NULL,
-					MAIL_TRANSACTION_KEYWORD_RESET,
+		ret = log_append_buffer(file, t->keyword_resets.arr.buffer,
+					NULL, MAIL_TRANSACTION_KEYWORD_RESET,
 					t->external);
 	}
 	if (array_is_created(&t->keyword_updates) && ret == 0)
@@ -485,7 +485,7 @@
 
 	if (array_is_created(&t->expunges) && ret == 0) {
 		/* Expunges cannot be hidden */
-		ret = log_append_buffer(file, t->expunges.buffer, NULL,
+		ret = log_append_buffer(file, t->expunges.arr.buffer, NULL,
 					MAIL_TRANSACTION_EXPUNGE, t->external);
 	}
 
--- a/src/lib-mail/mail-types.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-mail/mail-types.h	Wed Jun 28 16:10:25 2006 +0300
@@ -18,4 +18,6 @@
 	MODIFY_REPLACE
 };
 
+ARRAY_DEFINE_TYPE(keywords, const char *);
+
 #endif
--- a/src/lib-mail/message-body-search.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-mail/message-body-search.c	Wed Jun 28 16:10:25 2006 +0300
@@ -170,7 +170,7 @@
 	key = (const unsigned char *) ctx->body_ctx->key;
 	key_len = ctx->body_ctx->key_len;
 
-	matches = buffer_get_modifyable_data(ctx->match_buf, &match_count);
+	matches = buffer_get_modifiable_data(ctx->match_buf, &match_count);
 	match_count /= sizeof(size_t);
 
 	p = buffer_get_data(block, &block_size);
--- a/src/lib-mail/message-header-search.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-mail/message-header-search.c	Wed Jun 28 16:10:25 2006 +0300
@@ -126,7 +126,7 @@
 	unsigned char chr;
 	bool last_newline;
 
-	matches = buffer_get_modifyable_data(ctx->match_buf, &match_count);
+	matches = buffer_get_modifiable_data(ctx->match_buf, &match_count);
 	match_count /= sizeof(size_t);
 
 	last_newline = ctx->last_newline;
--- a/src/lib-sql/driver-mysql.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-sql/driver-mysql.c	Wed Jun 28 16:10:25 2006 +0300
@@ -33,7 +33,7 @@
 	const char *ssl_cert, *ssl_key, *ssl_ca, *ssl_ca_path, *ssl_cipher;
 	unsigned int port, client_flags;
 
-	array_t ARRAY_DEFINE(connections, struct mysql_connection);
+	ARRAY_DEFINE(connections, struct mysql_connection);
 	unsigned int next_query_connection;
 };
 
@@ -150,7 +150,7 @@
 	unsigned int i, count;
 	int ret = -1;
 
-	conn = array_get_modifyable(&db->connections, &count);
+	conn = array_get_modifiable(&db->connections, &count);
 	for (i = 0; i < count; i++) {
 		if (driver_mysql_connect(&conn[i]))
 			ret = 1;
@@ -260,7 +260,7 @@
 	struct mysql_connection *conn;
 	unsigned int i, count;
 
-	conn = array_get_modifyable(&db->connections, &count);
+	conn = array_get_modifiable(&db->connections, &count);
 	for (i = 0; i < count; i++)
 		(void)driver_mysql_connection_free(&conn[i]);
 
@@ -309,7 +309,7 @@
 	bool reset;
 	int ret;
 
-	conn = array_get_modifyable(&db->connections, &count);
+	conn = array_get_modifiable(&db->connections, &count);
 
 	/* go through the connections in round robin. if the connection
 	   isn't available, try next one that is. */
@@ -354,7 +354,7 @@
 
 	/* All the connections should be identical, so just use the first
 	   connected one */
-	conn = array_get_modifyable(&db->connections, &count);
+	conn = array_get_modifiable(&db->connections, &count);
 	for (i = 0; i < count; i++) {
 		if (conn[i].connected)
 			break;
--- a/src/lib-sql/sql-api-private.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-sql/sql-api-private.h	Wed Jun 28 16:10:25 2006 +0300
@@ -55,7 +55,9 @@
 	struct sql_db *db;
 };
 
-extern array_t ARRAY_DEFINE(sql_drivers, const struct sql_db *);
+ARRAY_DEFINE_TYPE(sql_drivers, const struct sql_db *);
+
+extern ARRAY_TYPE(sql_drivers) sql_drivers;
 extern struct sql_result sql_not_connected_result;
 
 #endif
--- a/src/lib-sql/sql-api.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-sql/sql-api.c	Wed Jun 28 16:10:25 2006 +0300
@@ -4,7 +4,7 @@
 #include "array.h"
 #include "sql-api-private.h"
 
-array_t ARRAY_DEFINE(sql_drivers, const struct sql_db *);
+ARRAY_TYPE(sql_drivers) sql_drivers;
 
 void sql_drivers_init(void)
 {
--- a/src/lib-storage/index/dbox/dbox-keywords.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/dbox/dbox-keywords.c	Wed Jun 28 16:10:25 2006 +0300
@@ -59,7 +59,7 @@
 		kw.file_idx = idx;
 
 		/* look up the position where to insert it */
-		map = array_get_modifyable(&file->idx_file_keywords, &count);
+		map = array_get_modifiable(&file->idx_file_keywords, &count);
 		pos = idx == 0 ? map :
 			bsearch_insert_pos(&kw, map, count, sizeof(*map),
 					   dbox_keyword_map_compare);
@@ -118,8 +118,7 @@
 			      const struct seq_range *idx_range,
 			      unsigned int count)
 {
-	const array_t *idx_keywords;
-	ARRAY_SET_TYPE(idx_keywords, const char *);
+	const ARRAY_TYPE(keywords) *idx_keywords;
 	string_t *keyword_str;
 	const char *const *idx_keyword_names;
 	unsigned int i, idx_keyword_count, new_pos;
--- a/src/lib-storage/index/dbox/dbox-save.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/dbox/dbox-save.c	Wed Jun 28 16:10:25 2006 +0300
@@ -43,7 +43,7 @@
 		       const struct mail_keywords *keywords,
 		       buffer_t *file_keywords)
 {
-	array_t ARRAY_DEFINE(new_keywords, struct seq_range);
+	ARRAY_TYPE(seq_range) new_keywords;
 	const struct seq_range *range;
 	unsigned int i, count, file_idx;
 	int ret = 0;
@@ -184,7 +184,7 @@
 		size_t size;
 
 		keyword_string =
-			buffer_get_modifyable_data(file_keywords, &size);
+			buffer_get_modifiable_data(file_keywords, &size);
 
 		/* string should be filled with NULs and '1' now.
 		   Change NULs to '0'. */
--- a/src/lib-storage/index/dbox/dbox-storage.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/dbox/dbox-storage.h	Wed Jun 28 16:10:25 2006 +0300
@@ -47,9 +47,9 @@
 	unsigned char *seeked_keywords;
 
 	/* Keywords list, sorted by index_idx. */
-	array_t ARRAY_DEFINE(idx_file_keywords, struct keyword_map);
+	ARRAY_DEFINE(idx_file_keywords, struct keyword_map);
 	/* idx -> index_idx array */
-	array_t ARRAY_DEFINE(file_idx_keywords, unsigned int);
+	ARRAY_DEFINE(file_idx_keywords, unsigned int);
 };
 
 struct dbox_mailbox {
--- a/src/lib-storage/index/dbox/dbox-sync-expunge.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/dbox/dbox-sync-expunge.c	Wed Jun 28 16:10:25 2006 +0300
@@ -306,7 +306,7 @@
 	/* find the first non-expunged mail */
 	first_expunged_uid = exp_uid1;
 	seen_expunges = FALSE; skipped_expunges = FALSE; uid = 0;
-	range = array_get_modifyable(&entry->uid_list, &count);
+	range = array_get_modifiable(&entry->uid_list, &count);
 	for (i = 0; i < count; i++) {
 		uid = range[i].seq1;
 
--- a/src/lib-storage/index/dbox/dbox-sync-full.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/dbox/dbox-sync-full.c	Wed Jun 28 16:10:25 2006 +0300
@@ -16,13 +16,11 @@
 
 static int
 dbox_mail_get_keywords(struct dbox_mailbox *mbox, struct dbox_file *file,
-		       array_t *keywords)
+		       ARRAY_TYPE(keyword_indexes) *keywords)
 {
 	const unsigned int *map;
 	unsigned int i, count;
 
-	ARRAY_SET_TYPE(keywords, unsigned int);
-
 	if (!array_is_created(&file->file_idx_keywords)) {
 		if (dbox_file_read_keywords(mbox, file) < 0)
 			return -1;
@@ -43,7 +41,7 @@
 	const struct dbox_mail_header *hdr = &mbox->file->seeked_mail_header;
 	enum mail_flags flags;
         struct mail_keywords *keywords;
-	array_t ARRAY_DEFINE(keywords_arr, unsigned int);
+	ARRAY_TYPE(keyword_indexes) keywords_arr;
 	uint32_t seq;
 	uint64_t hdr_offset = mbox->file->seeked_offset;
 
--- a/src/lib-storage/index/dbox/dbox-sync.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/dbox/dbox-sync.c	Wed Jun 28 16:10:25 2006 +0300
@@ -312,7 +312,7 @@
 			    const struct dbox_sync_file_entry *entry,
 			    unsigned int i)
 {
-	array_t ARRAY_DEFINE(keywords, struct seq_range);
+	ARRAY_TYPE(seq_range) keywords;
 	const struct dbox_sync_rec *sync_recs;
 	const struct seq_range *range;
 	unsigned int count, file_idx, keyword_idx;
--- a/src/lib-storage/index/dbox/dbox-sync.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/dbox/dbox-sync.h	Wed Jun 28 16:10:25 2006 +0300
@@ -1,6 +1,7 @@
 #ifndef __DBOX_SYNC_H
 #define __DBOX_SYNC_H
 
+#include "seq-range-array.h"
 #include "mail-index.h"
 #include "mail-storage.h"
 
@@ -26,7 +27,7 @@
 struct dbox_sync_file_entry {
 	uint32_t file_seq;
 
-	array_t ARRAY_DEFINE(sync_recs, struct dbox_sync_rec);
+	ARRAY_DEFINE(sync_recs, struct dbox_sync_rec);
 };
 
 struct dbox_sync_context {
@@ -38,13 +39,13 @@
 
 	pool_t pool;
 	struct hash_table *syncs; /* struct dbox_sync_file_entry */
-	array_t ARRAY_DEFINE(added_file_seqs, uint32_t);
+	ARRAY_DEFINE(added_file_seqs, uint32_t);
 
 	uint32_t dotlock_failed_file_seq;
 
 	/* full sync: */
 	uint32_t mail_index_next_uid;
-	array_t ARRAY_DEFINE(exists, struct seq_range);
+	ARRAY_TYPE(seq_range) exists;
 };
 
 int dbox_sync(struct dbox_mailbox *mbox, bool force);
--- a/src/lib-storage/index/dbox/dbox-uidlist.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/dbox/dbox-uidlist.c	Wed Jun 28 16:10:25 2006 +0300
@@ -34,7 +34,7 @@
 	ino_t ino;
 
 	struct dotlock *dotlock;
-	array_t ARRAY_DEFINE(seqs, unsigned int);
+	ARRAY_DEFINE(seqs, unsigned int);
 };
 
 struct dbox_uidlist {
@@ -54,7 +54,7 @@
 	uint32_t file_seq_highwater;
 
 	pool_t entry_pool;
-	array_t ARRAY_DEFINE(entries, struct dbox_uidlist_entry *);
+	ARRAY_DEFINE(entries, struct dbox_uidlist_entry *);
 
 	unsigned int appending:1;
 	unsigned int need_full_rewrite:1;
@@ -67,7 +67,7 @@
 	time_t min_usable_timestamp;
 	unsigned int mail_count;
 
-	array_t ARRAY_DEFINE(files, struct dbox_save_file *);
+	ARRAY_DEFINE(files, struct dbox_save_file *);
 	unsigned int open_fds;
 
 	unsigned int locked:1;
@@ -133,13 +133,12 @@
 	i_free(uidlist);
 }
 
-static int uidlist_merge(array_t *uid_list, const struct seq_range *seqs)
+static int uidlist_merge(ARRAY_TYPE(seq_range) *uid_list, const struct seq_range *seqs)
 {
-	ARRAY_SET_TYPE(uid_list, struct seq_range);
 	struct seq_range *range;
 	unsigned int count;
 
-	range = array_get_modifyable(uid_list, &count);
+	range = array_get_modifiable(uid_list, &count);
 	i_assert(count > 0);
 
 	if (seqs->seq1 <= range[count-1].seq2)
@@ -182,7 +181,7 @@
 
 	dbox_uidlist_update_last_uid(uidlist, src_entry);
 
-	entries = array_get_modifyable(&uidlist->entries, &count);
+	entries = array_get_modifiable(&uidlist->entries, &count);
 	if (count == 0 || src_entry->file_seq > entries[count-1]->file_seq) {
 		/* append new file sequence */
 		idx = count;
--- a/src/lib-storage/index/dbox/dbox-uidlist.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/dbox/dbox-uidlist.h	Wed Jun 28 16:10:25 2006 +0300
@@ -1,12 +1,14 @@
 #ifndef __DBOX_UIDLIST_H
 #define __DBOX_UIDLIST_H
 
+#include "seq-range-array.h"
+
 struct dbox_file;
 struct dbox_mailbox;
 struct dbox_uidlist_sync_ctx;
 
 struct dbox_uidlist_entry {
-	array_t ARRAY_DEFINE(uid_list, struct seq_range);
+	ARRAY_TYPE(seq_range) uid_list;
 
 	uint32_t file_seq;
 	/* file creation timestamp. used for rotation checks. */
--- a/src/lib-storage/index/index-mail-headers.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/index-mail-headers.c	Wed Jun 28 16:10:25 2006 +0300
@@ -46,7 +46,7 @@
 
 	t_push();
 
-	lines = array_get_modifyable(&mail->header_lines, &count);
+	lines = array_get_modifiable(&mail->header_lines, &count);
 
 	/* sort it first so fields are grouped together and ordered by
 	   line number */
@@ -299,7 +299,7 @@
 						  data->seq, field_idx);
 	}
 
-	match = array_get_modifyable(&mail->header_match, &count);
+	match = array_get_modifiable(&mail->header_match, &count);
 	if (field_idx < count && match[field_idx] == mail->header_match_value) {
 		/* first header */
 		match[field_idx]++;
@@ -464,7 +464,7 @@
 static const char *const *
 index_mail_get_parsed_header(struct index_mail *mail, unsigned int field_idx)
 {
-	array_t ARRAY_DEFINE(header_values, const char *);
+	ARRAY_DEFINE(header_values, const char *);
         const struct index_mail_line *lines;
 	const unsigned char *header, *value_start, *value_end;
 	const unsigned int *line_idx;
@@ -510,7 +510,7 @@
 	string_t *dest;
 	size_t i, len;
 	int ret;
-	array_t ARRAY_DEFINE(header_values, const char *);
+	ARRAY_DEFINE(header_values, const char *);
 
 	i_assert(field != NULL);
 
@@ -544,7 +544,7 @@
 		return ret == 0 ? NULL :
 			index_mail_get_parsed_header(mail, field_idx);
 	}
-	data = buffer_get_modifyable_data(dest, &len);
+	data = buffer_get_modifiable_data(dest, &len);
 
 	if (len == 0) {
 		/* cached as non-existing. */
--- a/src/lib-storage/index/index-mail.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/index-mail.c	Wed Jun 28 16:10:25 2006 +0300
@@ -146,7 +146,7 @@
 	static const char *const no_keywords[] = { NULL };
 	struct index_mail *mail = (struct index_mail *) _mail;
 	struct index_mail_data *data = &mail->data;
-	array_t ARRAY_DEFINE(keyword_indexes_arr, unsigned int);
+	ARRAY_TYPE(keyword_indexes) keyword_indexes_arr;
 	const char *const *names;
 	const unsigned int *keyword_indexes;
 	unsigned int i, count, names_count;
--- a/src/lib-storage/index/index-mail.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/index-mail.h	Wed Jun 28 16:10:25 2006 +0300
@@ -87,7 +87,7 @@
 	struct message_size hdr_size, body_size;
 	struct message_parser_ctx *parser_ctx;
 	int parsing_count;
-	array_t ARRAY_DEFINE(keywords, const char *);
+	ARRAY_TYPE(keywords) keywords;
 
 	const struct mail_cache_field *all_cache_fields;
 	unsigned int all_cache_fields_count;
@@ -119,9 +119,9 @@
 	/* per-mail variables, here for performance reasons: */
 	uint32_t header_seq;
 	string_t *header_data;
-	array_t ARRAY_DEFINE(header_lines, struct index_mail_line);
-	array_t ARRAY_DEFINE(header_match, uint8_t);
-	array_t ARRAY_DEFINE(header_match_lines, unsigned int);
+	ARRAY_DEFINE(header_lines, struct index_mail_line);
+	ARRAY_DEFINE(header_match, uint8_t);
+	ARRAY_DEFINE(header_match_lines, unsigned int);
 	uint8_t header_match_value;
 };
 
--- a/src/lib-storage/index/index-sort.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/index-sort.c	Wed Jun 28 16:10:25 2006 +0300
@@ -44,6 +44,7 @@
 	uint32_t seq;
 	uint32_t sort_id;
 };
+ARRAY_DEFINE_TYPE(mail_sort_node, struct mail_sort_node);
 
 struct mail_search_sort_program {
 	struct mailbox_transaction_context *t;
@@ -51,11 +52,11 @@
 	const char *primary_sort_header;
 	struct mail *temp_mail;
 
-	array_t ARRAY_DEFINE(nodes, struct mail_sort_node);
+	ARRAY_TYPE(mail_sort_node) nodes;
 	const struct mail_sort_node *nodes_ptr;
 	unsigned int nodes_count, iter_idx;
 
-	array_t ARRAY_DEFINE(all_nodes, struct mail_sort_node);
+	ARRAY_TYPE(mail_sort_node) all_nodes;
 
 	uint32_t ext_id;
 	uint32_t prev_seq, last_sorted_seq;
@@ -333,7 +334,7 @@
 	int ret = 1;
 
 	t_push();
-	nodes = array_get_modifyable(&program->all_nodes, &count);
+	nodes = array_get_modifiable(&program->all_nodes, &count);
 	if (nodes[idx2].sort_id != 0) {
 		i_assert(idx1 != idx2);
 		last_id = nodes[idx2].sort_id;
@@ -395,7 +396,7 @@
 	unsigned int i, count;
 	uint32_t sort_id, prev_sort_id, skip;
 
-	nodes = array_get_modifyable(&program->all_nodes, &count);
+	nodes = array_get_modifiable(&program->all_nodes, &count);
 	prev_sort_id = (uint32_t)-1;
 	sort_id = nodes[idx].sort_id;
 	i_assert(sort_id == nodes[idx + 1].sort_id);
@@ -522,7 +523,7 @@
 	static_node_cmp_context.program = program;
 	static_node_cmp_context.mail = mail;
 
-	qsort(array_idx_modifyable(&program->all_nodes, 0), last_seq,
+	qsort(array_idx_modifiable(&program->all_nodes, 0), last_seq,
 	      sizeof(struct mail_sort_node), sort_node_cmp);
 }
 
@@ -565,7 +566,7 @@
 	static_node_cmp_context.mail = program->temp_mail;
 
 	/* @UNSAFE */
-	nodes = array_get_modifyable(&program->all_nodes, &count);
+	nodes = array_get_modifiable(&program->all_nodes, &count);
 	if (program->last_sorted_seq != count) {
 		qsort(nodes, count, sizeof(struct mail_sort_node),
 		      sort_node_cmp);
@@ -576,7 +577,7 @@
 		index_sort_cache_seq(&static_node_cmp_context,
 				     program->sort_program[0], node.seq);
 
-		cnodes = array_get_modifyable(&program->nodes, &count);
+		cnodes = array_get_modifiable(&program->nodes, &count);
 		pos = bsearch_insert_pos(&node, cnodes, count, sizeof(*cnodes),
 					 sort_node_cmp_no_sort_id);
 		array_insert(&program->nodes, pos - cnodes, &node, 1);
--- a/src/lib-storage/index/index-storage.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/index-storage.h	Wed Jun 28 16:10:25 2006 +0300
@@ -62,7 +62,7 @@
 	uint32_t commit_log_file_seq;
 	uoff_t commit_log_file_offset;
 
-	const array_t *ARRAY_DEFINE_PTR(keyword_names, const char *);
+	const ARRAY_TYPE(keywords) *keyword_names;
 	struct mail_cache_field *cache_fields;
 	unsigned int mail_cache_min_mail_count;
 
@@ -183,6 +183,7 @@
 int index_transaction_commit(struct mailbox_transaction_context *t);
 void index_transaction_rollback(struct mailbox_transaction_context *t);
 
-bool index_keyword_array_cmp(const array_t *k1, const array_t *k2);
+bool index_keyword_array_cmp(const ARRAY_TYPE(keyword_indexes) *k1,
+			     const ARRAY_TYPE(keyword_indexes) *k2);
 
 #endif
--- a/src/lib-storage/index/index-sync.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/index-sync.c	Wed Jun 28 16:10:25 2006 +0300
@@ -30,7 +30,7 @@
 		dest_idx = ibox->recent_flags_start_seq - seq;
 		buffer_copy(ibox->recent_flags, dest_idx,
 			    ibox->recent_flags, 0, (size_t)-1);
-		memset(buffer_get_modifyable_data(ibox->recent_flags, NULL),
+		memset(buffer_get_modifiable_data(ibox->recent_flags, NULL),
 		       0, dest_idx);
 		ibox->recent_flags_start_seq = seq;
 	}
@@ -271,10 +271,9 @@
 	return ret;
 }
 
-bool index_keyword_array_cmp(const array_t *k1, const array_t *k2)
+bool index_keyword_array_cmp(const ARRAY_TYPE(keyword_indexes) *k1,
+			     const ARRAY_TYPE(keyword_indexes) *k2)
 {
-	ARRAY_SET_TYPE(k1, unsigned int);
-	ARRAY_SET_TYPE(k2, unsigned int);
 	const unsigned int *idx1, *idx2;
 	unsigned int i, j, count1, count2;
 
--- a/src/lib-storage/index/maildir/maildir-keywords.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/maildir/maildir-keywords.c	Wed Jun 28 16:10:25 2006 +0300
@@ -25,7 +25,7 @@
 	char *path;
 
 	pool_t pool;
-	array_t ARRAY_DEFINE(list, const char *);
+	ARRAY_TYPE(keywords) list;
 	struct hash_table *hash; /* name -> idx+1 */
 
         struct dotlock_settings dotlock_settings;
@@ -39,8 +39,8 @@
 	struct maildir_keywords *mk;
 	struct mail_index *index;
 
-	const array_t *ARRAY_DEFINE_PTR(keywords, const char *);
-	array_t ARRAY_DEFINE(idx_to_chr, char);
+	const ARRAY_TYPE(keywords) *keywords;
+	ARRAY_DEFINE(idx_to_chr, char);
 	unsigned int chridx_to_idx[MAILDIR_MAX_KEYWORDS];
 };
 
@@ -139,7 +139,7 @@
 		new_name = p_strdup(mk->pool, p);
 		hash_insert(mk->hash, new_name, POINTER_CAST(idx + 1));
 
-		strp = array_idx_modifyable(&mk->list, idx);
+		strp = array_idx_modifiable(&mk->list, idx);
 		*strp = new_name;
 	}
 	i_stream_destroy(&input);
@@ -189,7 +189,7 @@
 	new_name = p_strdup(mk->pool, name);
 	hash_insert(mk->hash, new_name, POINTER_CAST(chridx + 1));
 
-	strp = array_idx_modifyable(&mk->list, chridx);
+	strp = array_idx_modifiable(&mk->list, chridx);
 	*strp = new_name;
 
 	mk->changed = TRUE;
@@ -370,7 +370,7 @@
 	char *chr_p;
 	int chridx;
 
-	chr_p = array_idx_modifyable(&ctx->idx_to_chr, idx);
+	chr_p = array_idx_modifiable(&ctx->idx_to_chr, idx);
 	if (*chr_p != '\0')
 		return *chr_p;
 
--- a/src/lib-storage/index/maildir/maildir-save.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/maildir/maildir-save.c	Wed Jun 28 16:10:25 2006 +0300
@@ -44,7 +44,7 @@
 	struct maildir_filename *files, **files_tail;
 
 	buffer_t *keywords_buffer;
-	array_t ARRAY_DEFINE(keywords_array, unsigned int);
+	ARRAY_TYPE(keyword_indexes) keywords_array;
 
 	struct istream *input, *input2;
 	struct ostream *output;
--- a/src/lib-storage/index/maildir/maildir-storage.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/maildir/maildir-storage.c	Wed Jun 28 16:10:25 2006 +0300
@@ -762,7 +762,7 @@
 {
 	struct mailbox_list_context *ctx;
         struct mailbox_list *list;
-	array_t ARRAY_DEFINE(names_arr, const char *);
+	ARRAY_DEFINE(names_arr, const char *);
 	const char *oldpath, *newpath, *old_listname, *new_listname;
 	const char *const *names;
 	unsigned int i, count;
--- a/src/lib-storage/index/maildir/maildir-storage.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/maildir/maildir-storage.h	Wed Jun 28 16:10:25 2006 +0300
@@ -154,12 +154,12 @@
 
 int maildir_filename_get_flags(struct maildir_keywords_sync_ctx *ctx,
 			       const char *fname, enum mail_flags *flags_r,
-			       array_t *keywords);
+			       ARRAY_TYPE(keyword_indexes) *keywords);
 struct maildir_keywords_sync_ctx *
 maildir_sync_get_keywords_sync_ctx(struct maildir_index_sync_context *ctx);
 const char *maildir_filename_set_flags(struct maildir_keywords_sync_ctx *ctx,
 				       const char *fname, enum mail_flags flags,
-				       array_t *keywords);
+				       ARRAY_TYPE(keyword_indexes) *keywords);
 
 unsigned int maildir_hash(const void *p);
 int maildir_cmp(const void *p1, const void *p2);
--- a/src/lib-storage/index/maildir/maildir-sync.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/maildir/maildir-sync.c	Wed Jun 28 16:10:25 2006 +0300
@@ -214,7 +214,7 @@
         struct maildir_keywords_sync_ctx *keywords_sync_ctx;
 	struct mail_index_transaction *trans;
 
-	array_t ARRAY_DEFINE(sync_recs, struct mail_index_sync_rec);
+	ARRAY_DEFINE(sync_recs, struct mail_index_sync_rec);
 	uint32_t seq;
 	int dirty_state;
 };
@@ -227,9 +227,8 @@
 
 int maildir_filename_get_flags(struct maildir_keywords_sync_ctx *ctx,
 			       const char *fname, enum mail_flags *flags_r,
-                               array_t *keywords_r)
+                               ARRAY_TYPE(keyword_indexes) *keywords_r)
 {
-	ARRAY_SET_TYPE(keywords_r, unsigned int);
 	const char *info;
 
 	array_clear(keywords_r);
@@ -282,9 +281,9 @@
 
 static void
 maildir_filename_append_keywords(struct maildir_keywords_sync_ctx *ctx,
-				 array_t *keywords, string_t *str)
+				 ARRAY_TYPE(keyword_indexes) *keywords,
+				 string_t *str)
 {
-	ARRAY_SET_TYPE(keywords, unsigned int);
 	const unsigned int *indexes;
 	unsigned int i, count;
 	char chr;
@@ -299,7 +298,7 @@
 
 const char *maildir_filename_set_flags(struct maildir_keywords_sync_ctx *ctx,
 				       const char *fname, enum mail_flags flags,
-				       array_t *keywords)
+				       ARRAY_TYPE(keyword_indexes) *keywords)
 {
 	string_t *flags_str;
 	enum mail_flags flags_left;
@@ -402,7 +401,7 @@
 	const struct mail_index_sync_rec *recs;
 	const char *dir, *fname, *newfname, *newpath;
 	enum mail_flags flags;
-	array_t ARRAY_DEFINE(keywords, unsigned int);
+	ARRAY_TYPE(keyword_indexes) keywords;
 	unsigned int i, count;
 	uint8_t flags8;
 
@@ -418,7 +417,7 @@
 					 fname, &flags, &keywords);
 	flags8 = flags;
 
-	recs = array_get_modifyable(&ctx->sync_recs, &count);
+	recs = array_get_modifiable(&ctx->sync_recs, &count);
 	for (i = 0; i < count; i++) {
 		if (recs[i].uid1 != ctx->seq)
 			break;
@@ -473,7 +472,7 @@
 	uint32_t seq, uid;
 	bool expunged, flag_changed;
 
-	recs = array_get_modifyable(&ctx->sync_recs, &count);
+	recs = array_get_modifiable(&ctx->sync_recs, &count);
 	for (seq = recs[0].uid1; seq <= last_seq; seq++) {
 		expunged = flag_changed = FALSE;
 		for (i = 0; i < count; i++) {
@@ -514,7 +513,7 @@
 		for (i = count; i > 0; i--) {
 			if (++recs[i-1].uid1 > recs[i-1].uid2) {
 				array_delete(&ctx->sync_recs, i-1, 1);
-				recs = array_get_modifyable(&ctx->sync_recs,
+				recs = array_get_modifiable(&ctx->sync_recs,
 							    &count);
 				if (count == 0) {
 					/* all sync_recs committed */
@@ -937,8 +936,8 @@
         enum maildir_uidlist_rec_flag uflags;
 	const char *filename;
 	enum mail_flags flags;
-	array_t ARRAY_DEFINE(keywords, unsigned int);
-	array_t ARRAY_DEFINE(idx_keywords, unsigned int);
+	ARRAY_TYPE(keyword_indexes) keywords;
+	ARRAY_TYPE(keyword_indexes) idx_keywords;
 	uint32_t uid_validity, next_uid;
 	uint64_t value;
 	time_t old_new_sync_time;
--- a/src/lib-storage/index/maildir/maildir-uidlist.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/maildir/maildir-uidlist.c	Wed Jun 28 16:10:25 2006 +0300
@@ -650,7 +650,7 @@
 	struct maildir_uidlist_rec **rec_p;
 	size_t i, size;
 
-	rec_p = buffer_get_modifyable_data(uidlist->record_buf, &size);
+	rec_p = buffer_get_modifiable_data(uidlist->record_buf, &size);
 	size /= sizeof(*rec_p);
 
 	if (nonsynced) {
@@ -844,7 +844,7 @@
 
 	i_assert(UIDLIST_IS_LOCKED(uidlist));
 
-	rec_p = buffer_get_modifyable_data(uidlist->record_buf, &size);
+	rec_p = buffer_get_modifiable_data(uidlist->record_buf, &size);
 	size /= sizeof(*rec_p);
 
 	/* sort new files and assign UIDs for them */
@@ -878,7 +878,7 @@
 	size_t size;
 
 	/* buffer is unsorted, sort it by UID */
-	rec_p = buffer_get_modifyable_data(ctx->record_buf, &size);
+	rec_p = buffer_get_modifiable_data(ctx->record_buf, &size);
 	size /= sizeof(*rec_p);
 	qsort(rec_p, size, sizeof(*rec_p), maildir_uid_cmp);
 
--- a/src/lib-storage/index/mbox/mbox-save.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/mbox/mbox-save.c	Wed Jun 28 16:10:25 2006 +0300
@@ -239,8 +239,7 @@
 {
 	unsigned char space[MBOX_HEADER_PADDING+1 +
 			    sizeof("Content-Length: \n")-1 + MAX_INT_STRLEN];
-	const array_t *keyword_names_list;
-	ARRAY_SET_TYPE(keyword_names_list, const char *);
+	const ARRAY_TYPE(keywords) *keyword_names_list;
 	const char *const *keyword_names;
 	unsigned int i, count, keyword_names_count;
 
--- a/src/lib-storage/index/mbox/mbox-sync-parse.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/mbox/mbox-sync-parse.c	Wed Jun 28 16:10:25 2006 +0300
@@ -256,7 +256,7 @@
 static bool parse_x_keywords(struct mbox_sync_mail_context *ctx,
 			     struct message_header_line *hdr)
 {
-	array_t ARRAY_DEFINE(keyword_list, unsigned int);
+	ARRAY_TYPE(keyword_indexes) keyword_list;
 	const unsigned int *list;
 	string_t *keyword;
 	size_t keyword_start;
--- a/src/lib-storage/index/mbox/mbox-sync-private.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/mbox/mbox-sync-private.h	Wed Jun 28 16:10:25 2006 +0300
@@ -4,6 +4,8 @@
 #include "md5.h"
 #include "mail-index.h"
 
+ARRAY_DEFINE_TYPE(sync_recs, struct mail_index_sync_rec);
+
 enum mbox_sync_flags {
 	MBOX_SYNC_LAST_COMMIT	= 0x01,
 	MBOX_SYNC_HEADER	= 0x02,
@@ -43,7 +45,7 @@
 	uint32_t uid;
 	uint32_t idx_seq;
 
-	array_t ARRAY_DEFINE(keywords, unsigned int);
+	ARRAY_TYPE(keyword_indexes) keywords;
 	uint8_t flags;
 
 	unsigned int uid_broken:1;
@@ -111,8 +113,8 @@
 	uoff_t base_uid_last_offset;
 
 	/* mail state: */
-	array_t ARRAY_DEFINE(mails, struct mbox_sync_mail);
-	array_t ARRAY_DEFINE(syncs, struct mail_index_sync_rec);
+	ARRAY_DEFINE(mails, struct mbox_sync_mail);
+	ARRAY_TYPE(sync_recs) syncs;
 	struct mail_index_sync_rec sync_rec;
 
 	pool_t mail_keyword_pool;
--- a/src/lib-storage/index/mbox/mbox-sync-rewrite.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/mbox/mbox-sync-rewrite.c	Wed Jun 28 16:10:25 2006 +0300
@@ -456,7 +456,7 @@
 	i_assert(extra_space < OFF_T_MAX);
 	i_assert(sync_ctx->mbox->mbox_lock_type == F_WRLCK);
 
-	mails = array_get_modifyable(&sync_ctx->mails, &count);
+	mails = array_get_modifiable(&sync_ctx->mails, &count);
 	i_assert(count == last_seq - first_seq + 1);
 
 	/* if there's expunges in mails[], we would get more correct balancing
--- a/src/lib-storage/index/mbox/mbox-sync-update.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/mbox/mbox-sync-update.c	Wed Jun 28 16:10:25 2006 +0300
@@ -88,7 +88,7 @@
 	}
 
 	/* how many bytes do we have now? */
-	data = buffer_get_modifyable_data(ctx->header, &size);
+	data = buffer_get_modifiable_data(ctx->header, &size);
 	for (have = 0; pos < size; pos++) {
 		if (data[pos] == '\n' || data[pos] == '\r')
 			break;
@@ -119,10 +119,10 @@
 	ctx->mail.flags ^= MBOX_NONRECENT_KLUDGE;
 }
 
-static void keywords_append(struct mbox_sync_context *sync_ctx, string_t *dest,
-			    const array_t *keyword_indexes_arr)
+static void
+keywords_append(struct mbox_sync_context *sync_ctx, string_t *dest,
+		const ARRAY_TYPE(keyword_indexes) *keyword_indexes_arr)
 {
-	ARRAY_SET_TYPE(keyword_indexes_arr, unsigned int);
 	const char *const *keyword_names;
 	const unsigned int *keyword_indexes;
 	unsigned int i, idx_count, keywords_count;
@@ -444,8 +444,7 @@
 		array_append_array(&ctx->mail.keywords,
 				   &mail->keywords);
 		mbox_sync_update_xkeywords(ctx);
-	} else if (!buffer_cmp(ctx->mail.keywords.buffer,
-			       mail->keywords.buffer)) {
+	} else if (!array_cmp(&ctx->mail.keywords, &mail->keywords)) {
 		/* keywords changed. */
 		array_clear(&ctx->mail.keywords);
 		array_append_array(&ctx->mail.keywords,
--- a/src/lib-storage/index/mbox/mbox-sync.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/index/mbox/mbox-sync.c	Wed Jun 28 16:10:25 2006 +0300
@@ -75,13 +75,13 @@
 	return 0;
 }
 
-static void mbox_sync_array_delete_to(array_t *syncs_arr, uint32_t last_uid)
+static void mbox_sync_array_delete_to(ARRAY_TYPE(sync_recs) *syncs_arr,
+				      uint32_t last_uid)
 {
-	ARRAY_SET_TYPE(syncs_arr, struct mail_index_sync_rec);
 	struct mail_index_sync_rec *syncs;
 	unsigned int src, dest, count;
 
-	syncs = array_get_modifyable(syncs_arr, &count);
+	syncs = array_get_modifiable(syncs_arr, &count);
 
 	for (src = dest = 0; src < count; src++) {
 		i_assert(last_uid >= syncs[src].uid1);
@@ -134,9 +134,8 @@
 	return 1;
 }
 
-static bool mbox_sync_buf_have_expunges(array_t *syncs_arr)
+static bool mbox_sync_buf_have_expunges(ARRAY_TYPE(sync_recs) *syncs_arr)
 {
-	ARRAY_SET_TYPE(syncs_arr, struct mail_index_sync_rec);
 	const struct mail_index_sync_rec *syncs;
 	unsigned int i, count;
 
--- a/src/lib-storage/mail-storage-private.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/mail-storage-private.h	Wed Jun 28 16:10:25 2006 +0300
@@ -75,7 +75,7 @@
         enum mail_storage_lock_method lock_method;
 
 	/* Module-specific contexts. See mail_storage_module_id. */
-	array_t ARRAY_DEFINE(module_contexts, void);
+	ARRAY_DEFINE(module_contexts, void);
 
 	/* IMAP: Give a BAD reply instead of NO */
 	unsigned int syntax_error:1;
@@ -167,7 +167,7 @@
 	pool_t pool;
 
 	/* Module-specific contexts. See mail_storage_module_id. */
-	array_t ARRAY_DEFINE(module_contexts, void);
+	ARRAY_DEFINE(module_contexts, void);
 };
 
 struct mail_vfuncs {
@@ -209,7 +209,7 @@
 	struct mail_vfuncs v;
 
 	pool_t pool;
-	array_t ARRAY_DEFINE(module_contexts, void);
+	ARRAY_DEFINE(module_contexts, void);
 };
 
 struct mailbox_list_context {
@@ -220,7 +220,7 @@
 
 struct mailbox_transaction_context {
 	struct mailbox *box;
-	array_t ARRAY_DEFINE(module_contexts, void);
+	ARRAY_DEFINE(module_contexts, void);
 };
 
 struct mail_search_context {
--- a/src/lib-storage/mail-storage.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/mail-storage.c	Wed Jun 28 16:10:25 2006 +0300
@@ -25,7 +25,7 @@
 
 unsigned int mail_storage_module_id = 0;
 
-static array_t ARRAY_DEFINE(storages, struct mail_storage *);
+static ARRAY_DEFINE(storages, struct mail_storage *);
 
 void mail_storage_init(void)
 {
--- a/src/lib-storage/mail-storage.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib-storage/mail-storage.h	Wed Jun 28 16:10:25 2006 +0300
@@ -177,7 +177,7 @@
 
 	uint32_t first_unseen_seq;
 
-	const array_t *ARRAY_DEFINE_PTR(keywords, const char *);
+	const ARRAY_TYPE(keywords) *keywords;
 };
 
 struct mailbox_sync_rec {
--- a/src/lib/array-decl.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib/array-decl.h	Wed Jun 28 16:10:25 2006 +0300
@@ -1,23 +1,13 @@
 #ifndef __ARRAY_DECL_H
 #define __ARRAY_DECL_H
 
-#if defined (DEBUG) && defined (__GNUC__)
-#  define ARRAY_TYPE_CHECKS
-#endif
+#define ARRAY_DEFINE(name, array_type) union { struct array arr; array_type const *v; array_type *v_modifiable; } name
+#define ARRAY_INIT { { 0, 0 } }
 
-#ifdef ARRAY_TYPE_CHECKS
-#  define ARRAY_DEFINE(name, array_type) name; array_type *name ## __ ## type
-#  define ARRAY_DEFINE_EXTERN(name, array_type) \
-	name; extern array_type *name ## __ ## type
-#  define ARRAY_DEFINE_PTR(name, array_type) \
-	name; array_type **name ## __ ## type
-#  define ARRAY_INIT { 0, 0 }, 0
-#else
-#  define ARRAY_DEFINE(name, array_type) name
-#  define ARRAY_DEFINE_EXTERN(name, array_type) name
-#  define ARRAY_DEFINE_PTR(name, array_type) name
-#  define ARRAY_INIT { 0, 0 }
-#endif
+#define ARRAY_DEFINE_TYPE(name, array_type) \
+	union array ## __ ## name { struct array arr; array_type const *v; array_type *v_modifiable; }
+#define ARRAY_TYPE(name) \
+	union array ## __ ## name
 
 struct array {
 	buffer_t *buffer;
--- a/src/lib/array.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib/array.h	Wed Jun 28 16:10:25 2006 +0300
@@ -1,18 +1,15 @@
 #ifndef __ARRAY_H
 #define __ARRAY_H
 
-/* Array is a buffer accessible using fixed size elements. If DEBUG is
-   enabled, it also provides compile time type safety:
-
-   If DEBUG is enabled, an extra variable is defined along with the array
-   itself. This is used to cast array_idx() return value correctly, so
-   compiler gives a warning if it's assigned into variable with a different
-   type.
+/* Array is a buffer accessible using fixed size elements. As long as the
+   compiler provides typeof() function, the array provides type safety. If
+   a wrong type is tried to be added to the array, or if the array's contents
+   are tried to be used using a wrong type, the compiler will give a warning.
 
    Example usage:
 
    struct foo {
-	array_t ARRAY_DEFINE(bars, struct bar);
+	ARRAY_DEFINE(bars, struct bar);
 	...
    };
 
@@ -22,164 +19,160 @@
    struct bar *bar = array_idx(&foo->bars, 5);
    struct baz *baz = array_idx(&foo->bars, 5); // compiler warning
 
-   When passing array_t as a parameter to function, or when it's otherwise
-   accessed in a way that the extra variable cannot be accessed, the code
-   won't compile. For situations like those, there's a ARRAY_SET_TYPE() macro.
+   If you want to pass an array as a parameter to a function, you'll need to
+   create a type for the array using ARRAY_DEFINE_TYPE() and use the type in
+   the parameter using ARRAY_TYPE().
 
    Example:
 
-   void do_foo(array_t *bars) {
-	ARRAY_SET_TYPE(bars, struct foo);
+   ARRAY_DEFINE_TYPE(foo, struct foo);
+   void do_foo(ARRAY_TYPE(foo) *bars) {
 	struct foo *foo = array_idx(bars, 0);
    }
 */
 #include "array-decl.h"
 #include "buffer.h"
 
-#ifdef ARRAY_TYPE_CHECKS
-#  define ARRAY_CREATE(array, pool, array_type, init_count) STMT_START { \
-	array_type **_array_tmp = array ## __ ## type; _array_tmp = NULL; \
+#define ARRAY_CREATE(array, pool, array_type, init_count) STMT_START { \
+	array_type const *_array_tmp = (array)->v; _array_tmp = NULL; \
 	array_create(array, pool, sizeof(array_type), init_count); \
 	} STMT_END
-#  define ARRAY_SET_TYPE(array, array_type) \
-	array_type **array ## __ ## type = NULL
+
+#ifdef __GNUC__
+#  define ARRAY_TYPE_CAST_CONST(array) \
+	(typeof((array)->v))
+#  define ARRAY_TYPE_CAST_MODIFIABLE(array) \
+	(typeof((array)->v_modifiable))
+#  define ARRAY_TYPE_CHECK(array, data) \
+	typeof((array)->v_modifiable) __tmp_array_data2 __attr_unused__ = \
+		(typeof(const typeof(typeof(*(data)) *)))NULL;
 #else
-#  define ARRAY_CREATE(array, pool, array_type, init_count) \
-	array_create(array, pool, sizeof(array_type), init_count)
-/* The reason we do this for non-ARRAY_TYPE_CHECKS as well is because if we
-   left this empty, some compilers wouldn't like an extra ";" character at
-   the beginning of the function (eg. gcc 2.95).
-
-   However just declaring the variable gives "unused variable" warning.
-   I couldn't think of anything better, so we just use gcc-specific
-   unused-attribute to get rid of that with gcc. */
-#  define ARRAY_SET_TYPE(array, array_type) \
-	array_type **array ## __ ## type __attr_unused__ = NULL
+#  define ARRAY_TYPE_CAST_CONST(array)
+#  define ARRAY_TYPE_CAST_MODIFIABLE(array)
+#  define ARRAY_TYPE_CHECK(array, data)
 #endif
 
 static inline void
-array_create_from_buffer(array_t *array, buffer_t *buffer, size_t element_size)
+_array_create_from_buffer(struct array *array, buffer_t *buffer,
+			  size_t element_size)
 {
 	array->buffer = buffer;
 	array->element_size = element_size;
 }
+#define array_create_from_buffer(array, buffer, element_size) \
+	_array_create_from_buffer(&(array)->arr, buffer, element_size)
 
 static inline void
-array_create(array_t *array, pool_t pool,
-	     size_t element_size, unsigned int init_count)
+_array_create(struct array *array, pool_t pool,
+	      size_t element_size, unsigned int init_count)
 {
 	buffer_t *buffer;
 
         buffer = buffer_create_dynamic(pool, init_count * element_size);
-	array_create_from_buffer(array, buffer, element_size);
+	_array_create_from_buffer(array, buffer, element_size);
 }
+#define array_create(array, pool, element_size, init_count) \
+	_array_create(&(array)->arr, pool, element_size, init_count)
 
 static inline void
-array_free(array_t *array)
+_array_free(struct array *array)
 {
 	buffer_free(array->buffer);
 	array->buffer = NULL;
 }
+#define array_free(array) \
+	_array_free(&(array)->arr)
 
 static inline bool
-array_is_created(const array_t *array)
+_array_is_created(const struct array *array)
 {
 	return array->buffer != NULL;
 }
+#define array_is_created(array) \
+	_array_is_created(&(array)->arr)
 
 static inline void
-array_clear(array_t *array)
+_array_clear(struct array *array)
 {
 	buffer_set_used_size(array->buffer, 0);
 }
+#define array_clear(array) \
+	_array_clear(&(array)->arr)
 
 static inline void
-_array_append(array_t *array, const void *data, unsigned int count)
+_array_append(struct array *array, const void *data, unsigned int count)
 {
 	buffer_append(array->buffer, data, count * array->element_size);
 }
-#ifndef ARRAY_TYPE_CHECKS
-#  define array_append _array_append
-#else
-#  define array_append(array, data, count) STMT_START { \
-	typeof(const typeof(**(array ## __ ## type)) *) _array_tmp = data; \
-	_array_append(array, _array_tmp, count); \
-	} STMT_END
-#endif
+
+#define array_append(array, data, count) STMT_START { \
+	ARRAY_TYPE_CHECK(array, data) \
+	_array_append(&(array)->arr, data, count); \
+} STMT_END
 
 static inline void
-array_append_array(array_t *dest_array, const array_t *src_array)
+_array_append_array(struct array *dest_array, const struct array *src_array)
 {
 	i_assert(dest_array->element_size == src_array->element_size);
 	buffer_append_buf(dest_array->buffer, src_array->buffer, 0, (size_t)-1);
 }
+#define array_append_array(dest_array, src_array) \
+	_array_append_array(&(dest_array)->arr, &(src_array)->arr)
 
 static inline void
-_array_insert(array_t *array, unsigned int idx,
+_array_insert(struct array *array, unsigned int idx,
 	      const void *data, unsigned int count)
 {
 	buffer_insert(array->buffer, idx * array->element_size,
 		      data, count * array->element_size);
 }
-#ifndef ARRAY_TYPE_CHECKS
-#  define array_insert _array_insert
-#else
-#  define array_insert(array, idx, data, count) STMT_START { \
-	typeof(const typeof(**(array ## __ ## type)) *) _array_tmp = data; \
-	_array_insert(array, idx, _array_tmp, count); \
+
+#define array_insert(array, idx, data, count) STMT_START { \
+	ARRAY_TYPE_CHECK(array, data) \
+	_array_insert(&(array)->arr, idx, data, count); \
 	} STMT_END
-#endif
 
 static inline void
-array_delete(array_t *array, unsigned int idx, unsigned int count)
+_array_delete(struct array *array, unsigned int idx, unsigned int count)
 {
 	buffer_delete(array->buffer, idx * array->element_size,
 		      count * array->element_size);
 }
+#define array_delete(array, idx, count) \
+	_array_delete(&(array)->arr, idx, count)
 
 static inline const void *
-_array_get(const array_t *array, unsigned int *count_r)
+_array_get(const struct array *array, unsigned int *count_r)
 {
 	if (count_r != NULL)
 		*count_r = array->buffer->used / array->element_size;
 	return array->buffer->data;
 }
-#ifndef ARRAY_TYPE_CHECKS
-#  define array_get _array_get
-#else
-#  define array_get(array, count) \
-	(typeof(typeof(**array ## __ ## type) const *))_array_get(array, count)
-#endif
+#define array_get(array, count) \
+	ARRAY_TYPE_CAST_CONST(array)_array_get(&(array)->arr, count)
 
 static inline const void *
-_array_idx(const array_t *array, unsigned int idx)
+_array_idx(const struct array *array, unsigned int idx)
 {
 	i_assert(idx * array->element_size < array->buffer->used);
 	return CONST_PTR_OFFSET(array->buffer->data, idx * array->element_size);
 }
-#ifndef ARRAY_TYPE_CHECKS
-#  define array_idx _array_idx
-#else
-#  define array_idx(array, idx) \
-	(typeof(typeof(**array ## __ ## type) const *))_array_idx(array, idx)
-#endif
+#define array_idx(array, idx) \
+	ARRAY_TYPE_CAST_CONST(array)_array_idx(&(array)->arr, idx)
 
 static inline void *
-_array_get_modifyable(array_t *array, unsigned int *count_r)
+_array_get_modifiable(struct array *array, unsigned int *count_r)
 {
 	if (count_r != NULL)
 		*count_r = array->buffer->used / array->element_size;
-	return buffer_get_modifyable_data(array->buffer, NULL);
+	return buffer_get_modifiable_data(array->buffer, NULL);
 }
-#ifndef ARRAY_TYPE_CHECKS
-#  define array_get_modifyable _array_get_modifyable
-#else
-#  define array_get_modifyable(array, count) \
-	(typeof(*array ## __ ## type))_array_get_modifyable(array, count)
-#endif
+#define array_get_modifiable(array, count) \
+	ARRAY_TYPE_CAST_MODIFIABLE(array) \
+		_array_get_modifiable(&(array)->arr, count)
 
 static inline void *
-_array_idx_modifyable(array_t *array, unsigned int idx)
+_array_idx_modifiable(struct array *array, unsigned int idx)
 {
 	size_t pos;
 
@@ -191,15 +184,12 @@
 	}
 	return buffer_get_space_unsafe(array->buffer, pos, array->element_size);
 }
-#ifndef ARRAY_TYPE_CHECKS
-#  define array_idx_modifyable _array_idx_modifyable
-#else
-#  define array_idx_modifyable(array, count) \
-	(typeof(*array ## __ ## type))_array_idx_modifyable(array, count)
-#endif
+#define array_idx_modifiable(array, count) \
+	ARRAY_TYPE_CAST_MODIFIABLE(array) \
+		_array_idx_modifiable(&(array)->arr, count)
 
 static inline void
-_array_idx_set(array_t *array, unsigned int idx, const void *data)
+_array_idx_set(struct array *array, unsigned int idx, const void *data)
 {
 	size_t pos;
 
@@ -210,17 +200,13 @@
 	}
 	buffer_write(array->buffer, pos, data, array->element_size);
 }
-#ifndef ARRAY_TYPE_CHECKS
-#  define array_idx_set _array_idx_set
-#else
-#  define array_idx_set(array, idx, data) STMT_START { \
-	typeof(const typeof(**(array ## __ ## type)) *) _array_tmp = data; \
-	_array_idx_set(array, idx, _array_tmp); \
+#define array_idx_set(array, idx, data) STMT_START { \
+	ARRAY_TYPE_CHECK(array, data) \
+	_array_idx_set(&(array)->arr, idx, data); \
 	} STMT_END
-#endif
 
 static inline void *
-_array_append_space(array_t *array)
+_array_append_space(struct array *array)
 {
 	void *data;
 
@@ -228,15 +214,11 @@
 	memset(data, 0, array->element_size);
 	return data;
 }
-#ifndef ARRAY_TYPE_CHECKS
-#  define array_append_space _array_append_space
-#else
-#  define array_append_space(array) \
-	(typeof(*array ## __ ## type))_array_append_space(array)
-#endif
+#define array_append_space(array) \
+	ARRAY_TYPE_CAST_MODIFIABLE(array)_array_append_space(&(array)->arr)
 
 static inline void *
-_array_insert_space(array_t *array, unsigned int idx)
+_array_insert_space(struct array *array, unsigned int idx)
 {
 	void *data;
 	size_t pos;
@@ -249,29 +231,30 @@
 	memset(data, 0, array->element_size);
 	return data;
 }
-#ifndef ARRAY_TYPE_CHECKS
-#  define array_insert_space _array_insert_space
-#else
-#  define array_insert_space(array, idx) \
-	(typeof(*array ## __ ## type))_array_insert_space(array, idx)
-#endif
+#define array_insert_space(array, idx) \
+	ARRAY_TYPE_CAST_MODIFIABLE(array) \
+		_array_insert_space(&(array)->arr, idx)
 
 static inline unsigned int
-array_count(const array_t *array)
+_array_count(const struct array *array)
 {
 	return array->buffer->used / array->element_size;
 }
+#define array_count(array) \
+	_array_count(&(array)->arr)
 
 static inline bool
-array_cmp(const array_t *array1, const array_t *array2)
+_array_cmp(const struct array *array1, const struct array *array2)
 {
-	if (!array_is_created(array1) || array1->buffer->used == 0)
-		return !array_is_created(array2) || array2->buffer->used == 0;
+	if (!_array_is_created(array1) || array1->buffer->used == 0)
+		return !_array_is_created(array2) || array2->buffer->used == 0;
 
-	if (!array_is_created(array2))
+	if (!_array_is_created(array2))
 		return FALSE;
 
 	return buffer_cmp(array1->buffer, array2->buffer);
 }
+#define array_cmp(array1, array2) \
+	_array_cmp(&(array1)->arr, &(array2)->arr)
 
 #endif
--- a/src/lib/buffer.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib/buffer.c	Wed Jun 28 16:10:25 2006 +0300
@@ -265,7 +265,7 @@
 	return buffer_get_space_unsafe(buf, buf->used, size);
 }
 
-void *buffer_get_modifyable_data(const buffer_t *_buf, size_t *used_size_r)
+void *buffer_get_modifiable_data(const buffer_t *_buf, size_t *used_size_r)
 {
 	const struct real_buffer *buf = (const struct real_buffer *)_buf;
 
--- a/src/lib/buffer.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib/buffer.h	Wed Jun 28 16:10:25 2006 +0300
@@ -17,9 +17,9 @@
 
 /* Create a static sized buffer. Writes past this size will kill the program. */
 buffer_t *buffer_create_static_hard(pool_t pool, size_t size);
-/* Create a modifyable buffer from given data. */
+/* Create a modifiable buffer from given data. */
 buffer_t *buffer_create_data(pool_t pool, void *data, size_t size);
-/* Create a non-modifyable buffer from given data. */
+/* Create a non-modifiable buffer from given data. */
 buffer_t *buffer_create_const_data(pool_t pool, const void *data, size_t size);
 void buffer_update_const_data(buffer_t *buffer, const void *data, size_t size);
 /* Creates a dynamically growing buffer. Whenever write would exceed the
@@ -75,9 +75,9 @@
 void *buffer_append_space_unsafe(buffer_t *buf, size_t size);
 
 /* Like buffer_get_data(), but don't return it as const. Returns NULL if the
-   buffer is non-modifyable. WARNING: The returned address may become invalid
+   buffer is non-modifiable. WARNING: The returned address may become invalid
    if you add more data to buffer. */
-void *buffer_get_modifyable_data(const buffer_t *buf, size_t *used_size_r);
+void *buffer_get_modifiable_data(const buffer_t *buf, size_t *used_size_r);
 
 /* Set the "used size" of buffer, ie. 0 would set the buffer empty.
    Must not be used to grow buffer. */
--- a/src/lib/ioloop-epoll.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib/ioloop-epoll.c	Wed Jun 28 16:10:25 2006 +0300
@@ -34,7 +34,7 @@
 	struct epoll_event *events;
 
 	unsigned int idx_size;
-	array_t ARRAY_DEFINE(fd_index, struct io_list *);
+	ARRAY_DEFINE(fd_index, struct io_list *);
 };
 
 struct io_list {
@@ -150,7 +150,7 @@
 	int ret, op, fd = io->fd;
 	bool first;
 
-	list = array_idx_modifyable(&ctx->fd_index, fd);
+	list = array_idx_modifiable(&ctx->fd_index, fd);
 	if (*list == NULL)
 		*list = p_new(ioloop->pool, struct io_list, 1);
 
@@ -184,7 +184,7 @@
 	int ret, op;
 	bool last;
 
-	list = array_idx_modifyable(&ctx->fd_index, io->fd);
+	list = array_idx_modifiable(&ctx->fd_index, io->fd);
 	last = iolist_del(*list, io);
 
 	event.data.ptr = *list;
--- a/src/lib/istream.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib/istream.c	Wed Jun 28 16:10:25 2006 +0300
@@ -155,7 +155,7 @@
 		str_truncate(stream->line_str, 0);
 		str_append_n(stream->line_str, stream->buffer + stream->skip,
 			     end - stream->skip);
-		ret = str_c_modifyable(stream->line_str);
+		ret = str_c_modifiable(stream->line_str);
 	}
 
 	i++;
@@ -178,7 +178,7 @@
 	}
 
 	if (_stream->w_buffer == NULL) {
-		i_error("i_stream_next_line() called for unmodifyable stream");
+		i_error("i_stream_next_line() called for unmodifiable stream");
 		return NULL;
 	}
 
@@ -221,7 +221,7 @@
         return _stream->buffer + _stream->skip;
 }
 
-unsigned char *i_stream_get_modifyable_data(struct istream *stream,
+unsigned char *i_stream_get_modifiable_data(struct istream *stream,
 					    size_t *size)
 {
 	struct _istream *_stream = stream->real_stream;
--- a/src/lib/istream.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib/istream.h	Wed Jun 28 16:10:25 2006 +0300
@@ -88,7 +88,7 @@
 const unsigned char *i_stream_get_data(struct istream *stream, size_t *size);
 /* Like i_stream_get_data(), but returns non-const data. This only works with
    buffered streams (currently only file), others return NULL. */
-unsigned char *i_stream_get_modifyable_data(struct istream *stream,
+unsigned char *i_stream_get_modifiable_data(struct istream *stream,
 					    size_t *size);
 /* Like i_stream_get_data(), but read more when needed. Returns 1 if more
    than threshold bytes are available, 0 if less, -1 if error or EOF with no
--- a/src/lib/lib.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib/lib.h	Wed Jun 28 16:10:25 2006 +0300
@@ -29,7 +29,6 @@
 #include "imem.h"
 
 typedef struct buffer buffer_t;
-typedef struct array array_t;
 typedef struct buffer string_t;
 
 struct istream;
--- a/src/lib/module-dir.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib/module-dir.c	Wed Jun 28 16:10:25 2006 +0300
@@ -164,7 +164,7 @@
 	const char **module_names_arr;
 	struct module *modules, *module;
 	unsigned int i, count;
-	array_t ARRAY_DEFINE(names, const char *);
+	ARRAY_DEFINE(names, const char *);
 	pool_t pool;
 
 	if (getenv("DEBUG") != NULL)
@@ -195,7 +195,7 @@
 		array_append(&names, &name, 1);
 	}
 
-	names_p = array_get_modifyable(&names, NULL);
+	names_p = array_get_modifiable(&names, NULL);
 	count = array_count(&names);
 	qsort(names_p, count, sizeof(const char *), module_name_cmp);
 
--- a/src/lib/seq-range-array.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib/seq-range-array.c	Wed Jun 28 16:10:25 2006 +0300
@@ -4,13 +4,13 @@
 #include "array.h"
 #include "seq-range-array.h"
 
-static bool seq_range_lookup(array_t *array, uint32_t seq, unsigned int *idx_r)
+static bool seq_range_lookup(ARRAY_TYPE(seq_range) *array,
+			     uint32_t seq, unsigned int *idx_r)
 {
-        ARRAY_SET_TYPE(array, struct seq_range);
 	struct seq_range *data;
 	unsigned int idx, left_idx, right_idx, count;
 
-	data = array_get_modifyable(array, &count);
+	data = array_get_modifiable(array, &count);
 
 	idx = 0; left_idx = 0; right_idx = count;
 	while (left_idx < right_idx) {
@@ -31,20 +31,18 @@
 	return FALSE;
 }
 
-void seq_range_array_add(array_t *array, unsigned int init_count, uint32_t seq)
+void seq_range_array_add(ARRAY_TYPE(seq_range) *array,
+			 unsigned int init_count, uint32_t seq)
 {
-        ARRAY_SET_TYPE(array, struct seq_range);
 	struct seq_range *data, value;
 	unsigned int idx, count;
 
 	value.seq1 = value.seq2 = seq;
 
-	if (!array_is_created(array)) {
-		array_create(array, default_pool,
-			     sizeof(struct seq_range), init_count);
-	}
+	if (!array_is_created(array))
+		ARRAY_CREATE(array, default_pool, struct seq_range, init_count);
 
-	data = array_get_modifyable(array, &count);
+	data = array_get_modifiable(array, &count);
 	if (count == 0) {
 		array_append(array, &value, 1);
 		return;
@@ -102,16 +100,15 @@
 	}
 }
 
-void seq_range_array_remove(array_t *array, uint32_t seq)
+void seq_range_array_remove(ARRAY_TYPE(seq_range) *array, uint32_t seq)
 {
-        ARRAY_SET_TYPE(array, struct seq_range);
 	struct seq_range *data, value;
 	unsigned int idx, left_idx, right_idx, count;
 
 	if (!array_is_created(array))
 		return;
 
-	data = array_get_modifyable(array, &count);
+	data = array_get_modifiable(array, &count);
 	if (count == 0)
 		return;
 
@@ -174,7 +171,7 @@
 	}
 }
 
-bool seq_range_exists(array_t *array, uint32_t seq)
+bool seq_range_exists(ARRAY_TYPE(seq_range) *array, uint32_t seq)
 {
 	unsigned int idx;
 
--- a/src/lib/seq-range-array.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib/seq-range-array.h	Wed Jun 28 16:10:25 2006 +0300
@@ -5,8 +5,11 @@
 	uint32_t seq1, seq2;
 };
 
-void seq_range_array_add(array_t *array, unsigned int init_count, uint32_t seq);
-void seq_range_array_remove(array_t *array, uint32_t seq);
-bool seq_range_exists(array_t *array, uint32_t seq);
+ARRAY_DEFINE_TYPE(seq_range, struct seq_range);
+
+void seq_range_array_add(ARRAY_TYPE(seq_range) *array, unsigned int init_count,
+			 uint32_t seq);
+void seq_range_array_remove(ARRAY_TYPE(seq_range) *array, uint32_t seq);
+bool seq_range_exists(ARRAY_TYPE(seq_range) *array, uint32_t seq);
 
 #endif
--- a/src/lib/str.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib/str.c	Wed Jun 28 16:10:25 2006 +0300
@@ -50,10 +50,10 @@
 	return buffer_get_data(str, NULL);
 }
 
-char *str_c_modifyable(string_t *str)
+char *str_c_modifiable(string_t *str)
 {
 	str_add_nul(str);
-	return buffer_get_modifyable_data(str, NULL);
+	return buffer_get_modifiable_data(str, NULL);
 }
 
 size_t str_len(const string_t *str)
--- a/src/lib/str.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/lib/str.h	Wed Jun 28 16:10:25 2006 +0300
@@ -8,7 +8,7 @@
 
 const char *str_c(string_t *str);
 const unsigned char *str_data(const string_t *str);
-char *str_c_modifyable(string_t *str);
+char *str_c_modifiable(string_t *str);
 size_t str_len(const string_t *str);
 
 /* Append string/character */
--- a/src/master/mail-process.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/master/mail-process.c	Wed Jun 28 16:10:25 2006 +0300
@@ -400,7 +400,7 @@
 	pid_t pid;
 	uid_t uid;
 	gid_t gid;
-	array_t ARRAY_DEFINE(extra_args, const char *);
+	ARRAY_DEFINE(extra_args, const char *);
 	unsigned int i, count;
 	int err, ret, log_fd, nice;
 	bool home_given, nfs_check;
--- a/src/master/master-settings.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/master/master-settings.h	Wed Jun 28 16:10:25 2006 +0300
@@ -125,7 +125,7 @@
 
 	const char *imap_generated_capability;
 
-	array_t ARRAY_DEFINE(plugin_envs, const char *);
+	ARRAY_DEFINE(plugin_envs, const char *);
 };
 
 struct socket_settings {
@@ -223,7 +223,7 @@
 	struct auth_settings auth_defaults;
         struct namespace_settings *namespaces;
 
-	array_t ARRAY_DEFINE(dicts, const char *);
+	ARRAY_DEFINE(dicts, const char *);
 
 	gid_t login_gid;
 };
--- a/src/plugins/acl/acl-backend-vfile.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/plugins/acl/acl-backend-vfile.c	Wed Jun 28 16:10:25 2006 +0300
@@ -116,7 +116,7 @@
 static const char *const *
 acl_parse_rights(const char *acl, const char **error_r)
 {
-	array_t ARRAY_DEFINE(rights, const char *);
+	ARRAY_DEFINE(rights, const char *);
 	const char *const *names;
 	unsigned int i;
 
--- a/src/plugins/acl/acl-cache.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/plugins/acl/acl-cache.c	Wed Jun 28 16:10:25 2006 +0300
@@ -31,7 +31,7 @@
 	   rights can be added to the mapping. */
 	pool_t right_names_pool;
 	/* idx => right name. */
-	array_t ARRAY_DEFINE(right_idx_name_map, const char *);
+	ARRAY_DEFINE(right_idx_name_map, const char *);
 	/* name => idx */
 	struct hash_table *right_name_idx_map;
 };
--- a/src/plugins/acl/acl-mailbox.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/plugins/acl/acl-mailbox.c	Wed Jun 28 16:10:25 2006 +0300
@@ -14,7 +14,7 @@
 #include <sys/stat.h>
 
 #define ACL_CONTEXT(obj) \
-	*((void **)array_idx_modifyable(&(obj)->module_contexts, \
+	*((void **)array_idx_modifiable(&(obj)->module_contexts, \
 					acl_storage_module_id))
 
 struct acl_mailbox {
--- a/src/plugins/acl/acl-plugin.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/plugins/acl/acl-plugin.h	Wed Jun 28 16:10:25 2006 +0300
@@ -4,7 +4,7 @@
 #include "mail-storage-private.h"
 
 #define ACL_CONTEXT(obj) \
-	*((void **)array_idx_modifyable(&(obj)->module_contexts, \
+	*((void **)array_idx_modifiable(&(obj)->module_contexts, \
 					acl_storage_module_id))
 
 enum acl_storage_rights {
--- a/src/plugins/quota/quota-dirsize.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/plugins/quota/quota-dirsize.c	Wed Jun 28 16:10:25 2006 +0300
@@ -161,14 +161,15 @@
 	const char *path;
 	bool is_file;
 };
+ARRAY_DEFINE_TYPE(quota_count_path, struct quota_count_path);
 
-static void quota_count_path_add(array_t *paths, const char *path, bool is_file)
+static void quota_count_path_add(ARRAY_TYPE(quota_count_path) *paths,
+				 const char *path, bool is_file)
 {
-	ARRAY_SET_TYPE(paths, struct quota_count_path);
 	struct quota_count_path *count_path;
 	unsigned int i, count;
 
-	count_path = array_get_modifyable(paths, &count);
+	count_path = array_get_modifiable(paths, &count);
 	for (i = 0; i < count; i++) {
 		if (strncmp(count_path[i].path, path,
 			    strlen(count_path[i].path)) == 0) {
@@ -193,7 +194,7 @@
 get_quota_root_usage(struct dirsize_quota_root *root, uint64_t *value_r)
 {
 	struct mail_storage *const *storages;
-	array_t ARRAY_DEFINE(paths, struct quota_count_path);
+	ARRAY_TYPE(quota_count_path) paths;
 	const struct quota_count_path *count_paths;
 	unsigned int i, count;
 	const char *path;
--- a/src/plugins/quota/quota-private.h	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/plugins/quota/quota-private.h	Wed Jun 28 16:10:25 2006 +0300
@@ -9,7 +9,7 @@
 extern unsigned int quota_module_id;
 
 struct quota {
-	array_t ARRAY_DEFINE(setups, struct quota_setup *);
+	ARRAY_DEFINE(setups, struct quota_setup *);
 	char *last_error;
 };
 
@@ -20,7 +20,7 @@
 	char *data;
 
 	/* List of quota roots. It's array because there shouldn't be many. */
-	array_t ARRAY_DEFINE(roots, struct quota_root *);
+	ARRAY_DEFINE(roots, struct quota_root *);
 
 	unsigned int user_root:1;
 };
@@ -73,9 +73,9 @@
 	struct quota_backend_vfuncs v;
 
 	/* Mail storages using this quota root. */
-	array_t ARRAY_DEFINE(storages, struct mail_storage *);
+	ARRAY_DEFINE(storages, struct mail_storage *);
 	/* Module-specific contexts. See quota_module_id. */
-	array_t ARRAY_DEFINE(quota_module_contexts, void);
+	ARRAY_DEFINE(quota_module_contexts, void);
 
 	unsigned int user_root:1;
 };
@@ -88,8 +88,8 @@
 struct quota_transaction_context {
 	struct quota *quota;
 
-	array_t ARRAY_DEFINE(root_transactions,
-			     struct quota_root_transaction_context *);
+	ARRAY_DEFINE(root_transactions,
+		     struct quota_root_transaction_context *);
 	struct mail *mail;
 };
 
--- a/src/plugins/quota/quota-storage.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/plugins/quota/quota-storage.c	Wed Jun 28 16:10:25 2006 +0300
@@ -11,7 +11,7 @@
 #include <sys/stat.h>
 
 #define QUOTA_CONTEXT(obj) \
-	*((void **)array_idx_modifyable(&(obj)->module_contexts, \
+	*((void **)array_idx_modifiable(&(obj)->module_contexts, \
 					quota_storage_module_id))
 
 struct quota_mail_storage {
@@ -19,7 +19,7 @@
 	struct quota *quota;
 
 	/* List of quota roots this storage belongs to. */
-	array_t ARRAY_DEFINE(roots, struct quota_root *);
+	ARRAY_DEFINE(roots, struct quota_root *);
 };
 
 struct quota_mailbox {
--- a/src/plugins/quota/quota.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/plugins/quota/quota.c	Wed Jun 28 16:10:25 2006 +0300
@@ -131,7 +131,7 @@
 void quota_root_deinit(struct quota_root *root)
 {
 	/* make a copy, since root is freed */
-	array_t module_contexts = root->quota_module_contexts;
+	struct array module_contexts = root->quota_module_contexts.arr;
 	struct mail_storage *const *storage_p;
 	struct quota_root *const *roots;
 	unsigned int i, count;
@@ -154,7 +154,7 @@
 
 	array_free(&root->storages);
 	root->v.deinit(root);
-	array_free(&module_contexts);
+	_array_free(&module_contexts);
 }
 
 void quota_add_user_storage(struct quota *quota, struct mail_storage *storage)
--- a/src/plugins/trash/trash-plugin.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/plugins/trash/trash-plugin.c	Wed Jun 28 16:10:25 2006 +0300
@@ -16,7 +16,7 @@
 #define MAX_RETRY_COUNT 3
 
 #define TRASH_CONTEXT(obj) \
-	*((void **)array_idx_modifyable(&(obj)->quota_module_contexts, \
+	*((void **)array_idx_modifiable(&(obj)->quota_module_contexts, \
 					trash_quota_module_id))
 
 struct trash_quota_root {
@@ -46,7 +46,7 @@
 
 static pool_t config_pool;
 /* trash_boxes ordered by priority, highest first */
-static array_t ARRAY_DEFINE(trash_boxes, struct trash_mailbox);
+static ARRAY_DEFINE(trash_boxes, struct trash_mailbox);
 
 static int trash_clean_mailbox_open(struct trash_mailbox *trash)
 {
@@ -96,7 +96,7 @@
 	uint64_t size;
 	int ret = 0;
 
-	trashes = array_get_modifyable(&trash_boxes, &count);
+	trashes = array_get_modifiable(&trash_boxes, &count);
 	for (i = 0; i < count; ) {
 		/* expunge oldest mails first in all trash boxes with
 		   same priority */
@@ -251,7 +251,7 @@
 	i_stream_destroy(&input);
 	(void)close(fd);
 
-	qsort(array_get_modifyable(&trash_boxes, NULL),
+	qsort(array_get_modifiable(&trash_boxes, NULL),
 	      array_count(&trash_boxes), sizeof(struct trash_mailbox),
 	      trash_mailbox_priority_cmp);
 	return 0;
--- a/src/plugins/zlib/zlib-plugin.c	Wed Jun 28 01:51:47 2006 +0300
+++ b/src/plugins/zlib/zlib-plugin.c	Wed Jun 28 16:10:25 2006 +0300
@@ -15,7 +15,7 @@
 };
 
 #define ZLIB_CONTEXT(obj) \
-	*((void **)array_idx_modifyable(&(obj)->module_contexts, \
+	*((void **)array_idx_modifiable(&(obj)->module_contexts, \
 					zlib_storage_module_id))
 
 /* defined by imap, pop3, lda */