/* imap-fetch-body-data-specifier.c generated by valac 0.56.19, the Vala compiler
 * generated from imap-fetch-body-data-specifier.vala, do not modify */

/* Copyright 2016 Software Freedom Conservancy Inc.
 *
 * This software is licensed under the GNU Lesser General Public License
 * (version 2.1 or later).  See the COPYING file in this distribution.
 */

#include "geary-engine.h"
#include <glib.h>
#include <gee.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif

enum  {
	GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_0_PROPERTY,
	GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_PROPERTY,
	GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_REQUEST_HEADER_FIELDS_SPACE_PROPERTY,
	GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_NUM_PROPERTIES
};
static GParamSpec* geary_imap_fetch_body_data_specifier_properties[GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_string_free0(var) ((var == NULL) ? NULL : (var = (g_string_free (var, TRUE), NULL)))
#define _g_regex_unref0(var) ((var == NULL) ? NULL : (var = (g_regex_unref (var), NULL)))
#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);

struct _GearyImapFetchBodyDataSpecifierPrivate {
	GearyImapFetchBodyDataSpecifierSectionPart _section_part;
	gboolean _request_header_fields_space;
	gint* part_number;
	gint part_number_length1;
	gint _part_number_size_;
	gint subset_start;
	gint subset_count;
	GeeTreeSet* field_names;
	gboolean is_peek;
	gchar* hashable;
};

static gint GearyImapFetchBodyDataSpecifier_private_offset;
static gpointer geary_imap_fetch_body_data_specifier_parent_class = NULL;
static GeeHashableIface * geary_imap_fetch_body_data_specifier_gee_hashable_parent_iface = NULL;

static void geary_imap_fetch_body_data_specifier_set_section_part (GearyImapFetchBodyDataSpecifier* self,
                                                            GearyImapFetchBodyDataSpecifierSectionPart value);
static void geary_imap_fetch_body_data_specifier_set_request_header_fields_space (GearyImapFetchBodyDataSpecifier* self,
                                                                           gboolean value);
static void geary_imap_fetch_body_data_specifier_init (GearyImapFetchBodyDataSpecifier* self,
                                                GearyImapFetchBodyDataSpecifierSectionPart section_part,
                                                gint* part_number,
                                                gint part_number_length1,
                                                gint subset_start,
                                                gint subset_count,
                                                gchar** field_names,
                                                gint field_names_length1,
                                                gboolean is_peek,
                                                gboolean is_response);
static gint* _vala_array_dup4 (gint* self,
                        gssize length);
static gint _geary_ascii_strcmp_gcompare_data_func (gconstpointer a,
                                             gconstpointer b,
                                             gpointer self);
VALA_EXTERN gchar* geary_imap_fetch_body_data_specifier_serialize_response (GearyImapFetchBodyDataSpecifier* self);
static gchar* geary_imap_fetch_body_data_specifier_serialize_part_number (GearyImapFetchBodyDataSpecifier* self);
static gchar* geary_imap_fetch_body_data_specifier_serialize_field_names (GearyImapFetchBodyDataSpecifier* self);
static gchar* geary_imap_fetch_body_data_specifier_serialize_subset (GearyImapFetchBodyDataSpecifier* self,
                                                              gboolean is_request);
static void _vala_array_add6 (gint* * array,
                       gint* length,
                       gint* size,
                       gint value);
static gboolean geary_imap_fetch_body_data_specifier_real_equal_to (GeeHashable* base,
                                                             GearyImapFetchBodyDataSpecifier* other);
static guint geary_imap_fetch_body_data_specifier_real_hash (GeeHashable* base);
static void geary_imap_fetch_body_data_specifier_finalize (GObject * obj);
static GType geary_imap_fetch_body_data_specifier_get_type_once (void);
static void _vala_geary_imap_fetch_body_data_specifier_get_property (GObject * object,
                                                              guint property_id,
                                                              GValue * value,
                                                              GParamSpec * pspec);
static void _vala_geary_imap_fetch_body_data_specifier_set_property (GObject * object,
                                                              guint property_id,
                                                              const GValue * value,
                                                              GParamSpec * pspec);
static void _vala_array_destroy (gpointer array,
                          gssize array_length,
                          GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array,
                       gssize array_length,
                       GDestroyNotify destroy_func);
static gssize _vala_array_length (gpointer array);

static inline gpointer
geary_imap_fetch_body_data_specifier_get_instance_private (GearyImapFetchBodyDataSpecifier* self)
{
	return G_STRUCT_MEMBER_P (self, GearyImapFetchBodyDataSpecifier_private_offset);
}

/**
     * Specifies which section (or partial section) is being requested with this identifier.
     */
gchar*
geary_imap_fetch_body_data_specifier_section_part_serialize (GearyImapFetchBodyDataSpecifierSectionPart self)
{
	gchar* result;
	switch (self) {
		case GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_NONE:
		{
			gchar* _tmp0_;
			_tmp0_ = g_strdup ("");
			result = _tmp0_;
			return result;
		}
		case GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_HEADER:
		{
			gchar* _tmp1_;
			_tmp1_ = g_strdup ("header");
			result = _tmp1_;
			return result;
		}
		case GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_HEADER_FIELDS:
		{
			gchar* _tmp2_;
			_tmp2_ = g_strdup ("header.fields");
			result = _tmp2_;
			return result;
		}
		case GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_HEADER_FIELDS_NOT:
		{
			gchar* _tmp3_;
			_tmp3_ = g_strdup ("header.fields.not");
			result = _tmp3_;
			return result;
		}
		case GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_MIME:
		{
			gchar* _tmp4_;
			_tmp4_ = g_strdup ("mime");
			result = _tmp4_;
			return result;
		}
		case GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_TEXT:
		{
			gchar* _tmp5_;
			_tmp5_ = g_strdup ("text");
			result = _tmp5_;
			return result;
		}
		default:
		{
			g_assert_not_reached ();
		}
	}
}

GearyImapFetchBodyDataSpecifierSectionPart
geary_imap_fetch_body_data_specifier_section_part_deserialize (const gchar* value,
                                                               GError** error)
{
	gchar* _tmp0_;
	gchar* _tmp1_;
	GQuark _tmp3_ = 0U;
	static GQuark _tmp2_label0 = 0;
	static GQuark _tmp2_label1 = 0;
	static GQuark _tmp2_label2 = 0;
	static GQuark _tmp2_label3 = 0;
	static GQuark _tmp2_label4 = 0;
	GError* _inner_error0_ = NULL;
	GearyImapFetchBodyDataSpecifierSectionPart result;
	g_return_val_if_fail (value != NULL, 0);
	if (geary_string_is_empty (value)) {
		result = GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_NONE;
		return result;
	}
	_tmp0_ = geary_ascii_strdown (value);
	_tmp1_ = _tmp0_;
	_tmp3_ = (NULL == _tmp1_) ? 0 : g_quark_from_string (_tmp1_);
	g_free (_tmp1_);
	if (_tmp3_ == ((0 != _tmp2_label0) ? _tmp2_label0 : (_tmp2_label0 = g_quark_from_static_string ("header")))) {
		switch (0) {
			default:
			{
				result = GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_HEADER;
				return result;
			}
		}
	} else if (_tmp3_ == ((0 != _tmp2_label1) ? _tmp2_label1 : (_tmp2_label1 = g_quark_from_static_string ("header.fields")))) {
		switch (0) {
			default:
			{
				result = GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_HEADER_FIELDS;
				return result;
			}
		}
	} else if (_tmp3_ == ((0 != _tmp2_label2) ? _tmp2_label2 : (_tmp2_label2 = g_quark_from_static_string ("header.fields.not")))) {
		switch (0) {
			default:
			{
				result = GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_HEADER_FIELDS_NOT;
				return result;
			}
		}
	} else if (_tmp3_ == ((0 != _tmp2_label3) ? _tmp2_label3 : (_tmp2_label3 = g_quark_from_static_string ("mime")))) {
		switch (0) {
			default:
			{
				result = GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_MIME;
				return result;
			}
		}
	} else if (_tmp3_ == ((0 != _tmp2_label4) ? _tmp2_label4 : (_tmp2_label4 = g_quark_from_static_string ("text")))) {
		switch (0) {
			default:
			{
				result = GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_TEXT;
				return result;
			}
		}
	} else {
		switch (0) {
			default:
			{
				GError* _tmp4_;
				_tmp4_ = g_error_new (GEARY_IMAP_ERROR, GEARY_IMAP_ERROR_PARSE_ERROR, "Invalid SectionPart name \"%s\"", value);
				_inner_error0_ = _tmp4_;
				if (_inner_error0_->domain == GEARY_IMAP_ERROR) {
					g_propagate_error (error, _inner_error0_);
					return 0;
				} else {
					g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
					g_clear_error (&_inner_error0_);
					return 0;
				}
			}
		}
	}
}

gchar*
geary_imap_fetch_body_data_specifier_section_part_to_string (GearyImapFetchBodyDataSpecifierSectionPart self)
{
	gchar* _tmp0_;
	gchar* result;
	_tmp0_ = geary_imap_fetch_body_data_specifier_section_part_serialize (self);
	result = _tmp0_;
	return result;
}

 G_GNUC_NO_INLINE static GType
geary_imap_fetch_body_data_specifier_section_part_get_type_once (void)
{
	static const GEnumValue values[] = {{GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_NONE, "GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_NONE", "none"}, {GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_HEADER, "GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_HEADER", "header"}, {GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_HEADER_FIELDS, "GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_HEADER_FIELDS", "header-fields"}, {GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_HEADER_FIELDS_NOT, "GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_HEADER_FIELDS_NOT", "header-fields-not"}, {GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_MIME, "GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_MIME", "mime"}, {GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_TEXT, "GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_TEXT", "text"}, {0, NULL, NULL}};
	GType geary_imap_fetch_body_data_specifier_section_part_type_id;
	geary_imap_fetch_body_data_specifier_section_part_type_id = g_enum_register_static ("GearyImapFetchBodyDataSpecifierSectionPart", values);
	return geary_imap_fetch_body_data_specifier_section_part_type_id;
}

GType
geary_imap_fetch_body_data_specifier_section_part_get_type (void)
{
	static gsize geary_imap_fetch_body_data_specifier_section_part_type_id__once = 0;
	if (g_once_init_enter (&geary_imap_fetch_body_data_specifier_section_part_type_id__once)) {
		GType geary_imap_fetch_body_data_specifier_section_part_type_id;
		geary_imap_fetch_body_data_specifier_section_part_type_id = geary_imap_fetch_body_data_specifier_section_part_get_type_once ();
		g_once_init_leave (&geary_imap_fetch_body_data_specifier_section_part_type_id__once, geary_imap_fetch_body_data_specifier_section_part_type_id);
	}
	return geary_imap_fetch_body_data_specifier_section_part_type_id__once;
}

GearyImapFetchBodyDataSpecifierSectionPart
geary_imap_fetch_body_data_specifier_get_section_part (GearyImapFetchBodyDataSpecifier* self)
{
	GearyImapFetchBodyDataSpecifierSectionPart result;
	g_return_val_if_fail (GEARY_IMAP_IS_FETCH_BODY_DATA_SPECIFIER (self), 0);
	result = self->priv->_section_part;
	return result;
}

static void
geary_imap_fetch_body_data_specifier_set_section_part (GearyImapFetchBodyDataSpecifier* self,
                                                       GearyImapFetchBodyDataSpecifierSectionPart value)
{
	GearyImapFetchBodyDataSpecifierSectionPart old_value;
	g_return_if_fail (GEARY_IMAP_IS_FETCH_BODY_DATA_SPECIFIER (self));
	old_value = geary_imap_fetch_body_data_specifier_get_section_part (self);
	if (old_value != value) {
		self->priv->_section_part = value;
		g_object_notify_by_pspec ((GObject *) self, geary_imap_fetch_body_data_specifier_properties[GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_PROPERTY]);
	}
}

gboolean
geary_imap_fetch_body_data_specifier_get_request_header_fields_space (GearyImapFetchBodyDataSpecifier* self)
{
	gboolean result;
	g_return_val_if_fail (GEARY_IMAP_IS_FETCH_BODY_DATA_SPECIFIER (self), FALSE);
	result = self->priv->_request_header_fields_space;
	return result;
}

static void
geary_imap_fetch_body_data_specifier_set_request_header_fields_space (GearyImapFetchBodyDataSpecifier* self,
                                                                      gboolean value)
{
	gboolean old_value;
	g_return_if_fail (GEARY_IMAP_IS_FETCH_BODY_DATA_SPECIFIER (self));
	old_value = geary_imap_fetch_body_data_specifier_get_request_header_fields_space (self);
	if (old_value != value) {
		self->priv->_request_header_fields_space = value;
		g_object_notify_by_pspec ((GObject *) self, geary_imap_fetch_body_data_specifier_properties[GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_REQUEST_HEADER_FIELDS_SPACE_PROPERTY]);
	}
}

/**
     * Create a FetchBodyDataType with the various required and optional parameters specified.
     *
     * Set part_number to null to ignore.  Set subset_start less than zero to ignore.
     * subset_count must be greater than zero if subset_start is greater than zero.
     *
     * field_names are required for {@link SectionPart.HEADER_FIELDS} and
     * {@link SectionPart.HEADER_FIELDS_NOT} and must be null for all other {@link SectionPart}s.
     */
GearyImapFetchBodyDataSpecifier*
geary_imap_fetch_body_data_specifier_construct (GType object_type,
                                                GearyImapFetchBodyDataSpecifierSectionPart section_part,
                                                gint* part_number,
                                                gint part_number_length1,
                                                gint subset_start,
                                                gint subset_count,
                                                gchar** field_names,
                                                gint field_names_length1)
{
	GearyImapFetchBodyDataSpecifier * self = NULL;
	self = (GearyImapFetchBodyDataSpecifier*) geary_base_object_construct (object_type);
	geary_imap_fetch_body_data_specifier_init (self, section_part, part_number, (gint) part_number_length1, subset_start, subset_count, field_names, (gint) field_names_length1, FALSE, FALSE);
	return self;
}

GearyImapFetchBodyDataSpecifier*
geary_imap_fetch_body_data_specifier_new (GearyImapFetchBodyDataSpecifierSectionPart section_part,
                                          gint* part_number,
                                          gint part_number_length1,
                                          gint subset_start,
                                          gint subset_count,
                                          gchar** field_names,
                                          gint field_names_length1)
{
	return geary_imap_fetch_body_data_specifier_construct (GEARY_IMAP_TYPE_FETCH_BODY_DATA_SPECIFIER, section_part, part_number, part_number_length1, subset_start, subset_count, field_names, field_names_length1);
}

/**
     * Like FetchBodyDataType, but the /Seen flag will not be set when used on a message.
     */
GearyImapFetchBodyDataSpecifier*
geary_imap_fetch_body_data_specifier_construct_peek (GType object_type,
                                                     GearyImapFetchBodyDataSpecifierSectionPart section_part,
                                                     gint* part_number,
                                                     gint part_number_length1,
                                                     gint subset_start,
                                                     gint subset_count,
                                                     gchar** field_names,
                                                     gint field_names_length1)
{
	GearyImapFetchBodyDataSpecifier * self = NULL;
	self = (GearyImapFetchBodyDataSpecifier*) geary_base_object_construct (object_type);
	geary_imap_fetch_body_data_specifier_init (self, section_part, part_number, (gint) part_number_length1, subset_start, subset_count, field_names, (gint) field_names_length1, TRUE, FALSE);
	return self;
}

GearyImapFetchBodyDataSpecifier*
geary_imap_fetch_body_data_specifier_new_peek (GearyImapFetchBodyDataSpecifierSectionPart section_part,
                                               gint* part_number,
                                               gint part_number_length1,
                                               gint subset_start,
                                               gint subset_count,
                                               gchar** field_names,
                                               gint field_names_length1)
{
	return geary_imap_fetch_body_data_specifier_construct_peek (GEARY_IMAP_TYPE_FETCH_BODY_DATA_SPECIFIER, section_part, part_number, part_number_length1, subset_start, subset_count, field_names, field_names_length1);
}

GearyImapFetchBodyDataSpecifier*
geary_imap_fetch_body_data_specifier_construct_response (GType object_type,
                                                         GearyImapFetchBodyDataSpecifierSectionPart section_part,
                                                         gint* part_number,
                                                         gint part_number_length1,
                                                         gint subset_start,
                                                         gchar** field_names,
                                                         gint field_names_length1)
{
	GearyImapFetchBodyDataSpecifier * self = NULL;
	self = (GearyImapFetchBodyDataSpecifier*) geary_base_object_construct (object_type);
	geary_imap_fetch_body_data_specifier_init (self, section_part, part_number, (gint) part_number_length1, subset_start, -1, field_names, (gint) field_names_length1, FALSE, TRUE);
	return self;
}

GearyImapFetchBodyDataSpecifier*
geary_imap_fetch_body_data_specifier_new_response (GearyImapFetchBodyDataSpecifierSectionPart section_part,
                                                   gint* part_number,
                                                   gint part_number_length1,
                                                   gint subset_start,
                                                   gchar** field_names,
                                                   gint field_names_length1)
{
	return geary_imap_fetch_body_data_specifier_construct_response (GEARY_IMAP_TYPE_FETCH_BODY_DATA_SPECIFIER, section_part, part_number, part_number_length1, subset_start, field_names, field_names_length1);
}

static gint*
_vala_array_dup4 (gint* self,
                  gssize length)
{
	if (length > 0) {
		return g_memdup2 (self, length * sizeof (gint));
	}
	return NULL;
}

static gint
_geary_ascii_strcmp_gcompare_data_func (gconstpointer a,
                                        gconstpointer b,
                                        gpointer self)
{
	gint result;
	result = geary_ascii_strcmp ((const gchar*) a, (const gchar*) b);
	return result;
}

static gchar*
string_strip (const gchar* self)
{
	gchar* _result_ = NULL;
	gchar* _tmp0_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = g_strdup (self);
	_result_ = _tmp0_;
	g_strstrip (_result_);
	result = _result_;
	return result;
}

static void
geary_imap_fetch_body_data_specifier_init (GearyImapFetchBodyDataSpecifier* self,
                                           GearyImapFetchBodyDataSpecifierSectionPart section_part,
                                           gint* part_number,
                                           gint part_number_length1,
                                           gint subset_start,
                                           gint subset_count,
                                           gchar** field_names,
                                           gint field_names_length1,
                                           gboolean is_peek,
                                           gboolean is_response)
{
	gboolean _tmp1_ = FALSE;
	gint* _tmp2_;
	gint _tmp2__length1;
	gboolean _tmp3_ = FALSE;
	gchar* _tmp14_;
	g_return_if_fail (GEARY_IMAP_IS_FETCH_BODY_DATA_SPECIFIER (self));
	switch (section_part) {
		case GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_HEADER_FIELDS:
		case GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_HEADER_FIELDS_NOT:
		{
			gboolean _tmp0_ = FALSE;
			if (field_names != NULL) {
				_tmp0_ = field_names_length1 > 0;
			} else {
				_tmp0_ = FALSE;
			}
			_vala_assert (_tmp0_, "field_names != null && field_names.length > 0");
			break;
		}
		default:
		{
			_vala_assert (field_names == NULL, "field_names == null");
			break;
		}
	}
	if (subset_start >= 0) {
		_tmp1_ = !is_response;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		_vala_assert (subset_count > 0, "subset_count > 0");
	}
	geary_imap_fetch_body_data_specifier_set_section_part (self, section_part);
	_tmp2_ = (part_number != NULL) ? _vala_array_dup4 (part_number, part_number_length1) : part_number;
	_tmp2__length1 = part_number_length1;
	self->priv->part_number = (g_free (self->priv->part_number), NULL);
	self->priv->part_number = _tmp2_;
	self->priv->part_number_length1 = _tmp2__length1;
	self->priv->_part_number_size_ = self->priv->part_number_length1;
	self->priv->subset_start = subset_start;
	self->priv->subset_count = subset_count;
	self->priv->is_peek = is_peek;
	if (field_names != NULL) {
		_tmp3_ = field_names_length1 > 0;
	} else {
		_tmp3_ = FALSE;
	}
	if (_tmp3_) {
		GeeTreeSet* _tmp4_;
		_tmp4_ = gee_tree_set_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, _geary_ascii_strcmp_gcompare_data_func, NULL, NULL);
		_g_object_unref0 (self->priv->field_names);
		self->priv->field_names = _tmp4_;
		{
			gchar** field_name_collection = NULL;
			gint field_name_collection_length1 = 0;
			gint _field_name_collection_size_ = 0;
			gint field_name_it = 0;
			field_name_collection = field_names;
			field_name_collection_length1 = field_names_length1;
			for (field_name_it = 0; field_name_it < field_name_collection_length1; field_name_it = field_name_it + 1) {
				gchar* _tmp5_;
				gchar* field_name = NULL;
				_tmp5_ = g_strdup (field_name_collection[field_name_it]);
				field_name = _tmp5_;
				{
					gchar* converted = NULL;
					const gchar* _tmp6_;
					gchar* _tmp7_;
					gchar* _tmp8_;
					gchar* _tmp9_;
					gchar* _tmp10_;
					const gchar* _tmp11_;
					_tmp6_ = field_name;
					_tmp7_ = string_strip (_tmp6_);
					_tmp8_ = _tmp7_;
					_tmp9_ = geary_ascii_strdown (_tmp8_);
					_tmp10_ = _tmp9_;
					_g_free0 (_tmp8_);
					converted = _tmp10_;
					_tmp11_ = converted;
					if (!geary_string_is_empty (_tmp11_)) {
						GeeTreeSet* _tmp12_;
						const gchar* _tmp13_;
						_tmp12_ = self->priv->field_names;
						_tmp13_ = converted;
						gee_abstract_collection_add (G_TYPE_CHECK_INSTANCE_CAST (_tmp12_, GEE_TYPE_ABSTRACT_COLLECTION, GeeAbstractCollection), _tmp13_);
					}
					_g_free0 (converted);
					_g_free0 (field_name);
				}
			}
		}
	} else {
		_g_object_unref0 (self->priv->field_names);
		self->priv->field_names = NULL;
	}
	_tmp14_ = geary_imap_fetch_body_data_specifier_serialize_response (self);
	_g_free0 (self->priv->hashable);
	self->priv->hashable = _tmp14_;
}

/**
     * Returns the {@link FetchBodyDataSpecifier} in a string ready for a {@link Command}.
     *
     * The serialized field names are returned in a case-insensitive casefolded order.
     * (Some servers return field names in arbitrary order.)
     */
gchar*
geary_imap_fetch_body_data_specifier_serialize_request (GearyImapFetchBodyDataSpecifier* self)
{
	const gchar* _tmp0_ = NULL;
	gchar* _tmp1_;
	gchar* _tmp2_;
	GearyImapFetchBodyDataSpecifierSectionPart _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	gchar* _tmp6_;
	gchar* _tmp7_;
	gchar* _tmp8_;
	gchar* _tmp9_;
	gchar* _tmp10_;
	gchar* _tmp11_;
	gchar* result;
	g_return_val_if_fail (GEARY_IMAP_IS_FETCH_BODY_DATA_SPECIFIER (self), NULL);
	if (!self->priv->is_peek) {
		_tmp0_ = "body[%s%s%s]%s";
	} else {
		_tmp0_ = "body.peek[%s%s%s]%s";
	}
	_tmp1_ = geary_imap_fetch_body_data_specifier_serialize_part_number (self);
	_tmp2_ = _tmp1_;
	_tmp3_ = self->priv->_section_part;
	_tmp4_ = geary_imap_fetch_body_data_specifier_section_part_serialize (_tmp3_);
	_tmp5_ = _tmp4_;
	_tmp6_ = geary_imap_fetch_body_data_specifier_serialize_field_names (self);
	_tmp7_ = _tmp6_;
	_tmp8_ = geary_imap_fetch_body_data_specifier_serialize_subset (self, TRUE);
	_tmp9_ = _tmp8_;
	_tmp10_ = g_strdup_printf (_tmp0_, _tmp2_, _tmp5_, _tmp7_, _tmp9_);
	_tmp11_ = _tmp10_;
	_g_free0 (_tmp9_);
	_g_free0 (_tmp7_);
	_g_free0 (_tmp5_);
	_g_free0 (_tmp2_);
	result = _tmp11_;
	return result;
}

/**
     * Returns the {@link FetchBodyDataSpecifier} in a string as it might appear in a
     * {@link ServerResponse}.
     *
     * The FetchBodyDataType server response does not include the peek modifier or the span
     * length if a span was indicated (as the following literal specifies its length).
     *
     * The serialized field names are returned in a case-insensitive casefolded order.
     * (Some servers return field names in arbitrary order.)
     *
     * See [[http://tools.ietf.org/html/rfc3501#section-7.4.2]]
     */
gchar*
geary_imap_fetch_body_data_specifier_serialize_response (GearyImapFetchBodyDataSpecifier* self)
{
	gchar* _tmp0_;
	gchar* _tmp1_;
	GearyImapFetchBodyDataSpecifierSectionPart _tmp2_;
	gchar* _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	gchar* _tmp6_;
	gchar* _tmp7_;
	gchar* _tmp8_;
	gchar* _tmp9_;
	gchar* _tmp10_;
	gchar* result;
	g_return_val_if_fail (GEARY_IMAP_IS_FETCH_BODY_DATA_SPECIFIER (self), NULL);
	_tmp0_ = geary_imap_fetch_body_data_specifier_serialize_part_number (self);
	_tmp1_ = _tmp0_;
	_tmp2_ = self->priv->_section_part;
	_tmp3_ = geary_imap_fetch_body_data_specifier_section_part_serialize (_tmp2_);
	_tmp4_ = _tmp3_;
	_tmp5_ = geary_imap_fetch_body_data_specifier_serialize_field_names (self);
	_tmp6_ = _tmp5_;
	_tmp7_ = geary_imap_fetch_body_data_specifier_serialize_subset (self, FALSE);
	_tmp8_ = _tmp7_;
	_tmp9_ = g_strdup_printf ("body[%s%s%s]%s", _tmp1_, _tmp4_, _tmp6_, _tmp8_);
	_tmp10_ = _tmp9_;
	_g_free0 (_tmp8_);
	_g_free0 (_tmp6_);
	_g_free0 (_tmp4_);
	_g_free0 (_tmp1_);
	result = _tmp10_;
	return result;
}

GearyImapParameter*
geary_imap_fetch_body_data_specifier_to_request_parameter (GearyImapFetchBodyDataSpecifier* self)
{
	gchar* _tmp0_;
	gchar* _tmp1_;
	GearyImapAtomParameter* _tmp2_;
	GearyImapParameter* _tmp3_;
	GearyImapParameter* result;
	g_return_val_if_fail (GEARY_IMAP_IS_FETCH_BODY_DATA_SPECIFIER (self), NULL);
	_tmp0_ = geary_imap_fetch_body_data_specifier_serialize_request (self);
	_tmp1_ = _tmp0_;
	_tmp2_ = geary_imap_atom_parameter_new (_tmp1_);
	_tmp3_ = G_TYPE_CHECK_INSTANCE_CAST (_tmp2_, GEARY_IMAP_TYPE_PARAMETER, GearyImapParameter);
	_g_free0 (_tmp1_);
	result = _tmp3_;
	return result;
}

static gchar*
geary_imap_fetch_body_data_specifier_serialize_part_number (GearyImapFetchBodyDataSpecifier* self)
{
	gboolean _tmp0_ = FALSE;
	gint* _tmp1_;
	gint _tmp1__length1;
	GString* builder = NULL;
	GString* _tmp4_;
	gint* _tmp5_;
	gint _tmp5__length1;
	GearyImapFetchBodyDataSpecifierSectionPart _tmp9_;
	GString* _tmp11_;
	const gchar* _tmp12_;
	gchar* _tmp13_;
	gchar* result;
	g_return_val_if_fail (GEARY_IMAP_IS_FETCH_BODY_DATA_SPECIFIER (self), NULL);
	_tmp1_ = self->priv->part_number;
	_tmp1__length1 = self->priv->part_number_length1;
	if (_tmp1_ == NULL) {
		_tmp0_ = TRUE;
	} else {
		gint* _tmp2_;
		gint _tmp2__length1;
		_tmp2_ = self->priv->part_number;
		_tmp2__length1 = self->priv->part_number_length1;
		_tmp0_ = _tmp2__length1 == 0;
	}
	if (_tmp0_) {
		gchar* _tmp3_;
		_tmp3_ = g_strdup ("");
		result = _tmp3_;
		return result;
	}
	_tmp4_ = g_string_new ("");
	builder = _tmp4_;
	_tmp5_ = self->priv->part_number;
	_tmp5__length1 = self->priv->part_number_length1;
	{
		gint* part_collection = NULL;
		gint part_collection_length1 = 0;
		gint _part_collection_size_ = 0;
		gint part_it = 0;
		part_collection = _tmp5_;
		part_collection_length1 = _tmp5__length1;
		for (part_it = 0; part_it < part_collection_length1; part_it = part_it + 1) {
			gint part = 0;
			part = part_collection[part_it];
			{
				GString* _tmp6_;
				GString* _tmp8_;
				_tmp6_ = builder;
				if (_tmp6_->len > ((gssize) 0)) {
					GString* _tmp7_;
					_tmp7_ = builder;
					g_string_append_c (_tmp7_, '.');
				}
				_tmp8_ = builder;
				g_string_append_printf (_tmp8_, "%d", part);
			}
		}
	}
	_tmp9_ = self->priv->_section_part;
	if (_tmp9_ != GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_NONE) {
		GString* _tmp10_;
		_tmp10_ = builder;
		g_string_append_c (_tmp10_, '.');
	}
	_tmp11_ = builder;
	_tmp12_ = _tmp11_->str;
	_tmp13_ = g_strdup (_tmp12_);
	result = _tmp13_;
	_g_string_free0 (builder);
	return result;
}

static gchar*
geary_imap_fetch_body_data_specifier_serialize_field_names (GearyImapFetchBodyDataSpecifier* self)
{
	gboolean _tmp0_ = FALSE;
	GeeTreeSet* _tmp1_;
	const gchar* _tmp6_ = NULL;
	gboolean _tmp7_;
	GString* builder = NULL;
	GString* _tmp8_;
	GeeIterator* iter = NULL;
	GeeTreeSet* _tmp9_;
	GeeIterator* _tmp10_;
	GString* _tmp18_;
	GString* _tmp19_;
	const gchar* _tmp20_;
	gchar* _tmp21_;
	gchar* result;
	g_return_val_if_fail (GEARY_IMAP_IS_FETCH_BODY_DATA_SPECIFIER (self), NULL);
	_tmp1_ = self->priv->field_names;
	if (_tmp1_ == NULL) {
		_tmp0_ = TRUE;
	} else {
		GeeTreeSet* _tmp2_;
		gint _tmp3_;
		gint _tmp4_;
		_tmp2_ = self->priv->field_names;
		_tmp3_ = gee_abstract_collection_get_size (G_TYPE_CHECK_INSTANCE_CAST (_tmp2_, GEE_TYPE_ABSTRACT_COLLECTION, GeeAbstractCollection));
		_tmp4_ = _tmp3_;
		_tmp0_ = _tmp4_ == 0;
	}
	if (_tmp0_) {
		gchar* _tmp5_;
		_tmp5_ = g_strdup ("");
		result = _tmp5_;
		return result;
	}
	_tmp7_ = self->priv->_request_header_fields_space;
	if (_tmp7_) {
		_tmp6_ = " (";
	} else {
		_tmp6_ = "(";
	}
	_tmp8_ = g_string_new (_tmp6_);
	builder = _tmp8_;
	_tmp9_ = self->priv->field_names;
	_tmp10_ = gee_abstract_collection_iterator (G_TYPE_CHECK_INSTANCE_CAST (_tmp9_, GEE_TYPE_ABSTRACT_COLLECTION, GeeAbstractCollection));
	iter = _tmp10_;
	while (TRUE) {
		GeeIterator* _tmp11_;
		GString* _tmp12_;
		GeeIterator* _tmp13_;
		gpointer _tmp14_;
		gchar* _tmp15_;
		GeeIterator* _tmp16_;
		_tmp11_ = iter;
		if (!gee_iterator_next (_tmp11_)) {
			break;
		}
		_tmp12_ = builder;
		_tmp13_ = iter;
		_tmp14_ = gee_iterator_get (_tmp13_);
		_tmp15_ = (gchar*) _tmp14_;
		g_string_append (_tmp12_, _tmp15_);
		_g_free0 (_tmp15_);
		_tmp16_ = iter;
		if (gee_iterator_has_next (_tmp16_)) {
			GString* _tmp17_;
			_tmp17_ = builder;
			g_string_append_c (_tmp17_, ' ');
		}
	}
	_tmp18_ = builder;
	g_string_append_c (_tmp18_, ')');
	_tmp19_ = builder;
	_tmp20_ = _tmp19_->str;
	_tmp21_ = g_strdup (_tmp20_);
	result = _tmp21_;
	_g_object_unref0 (iter);
	_g_string_free0 (builder);
	return result;
}

static gchar*
geary_imap_fetch_body_data_specifier_serialize_subset (GearyImapFetchBodyDataSpecifier* self,
                                                       gboolean is_request)
{
	gboolean _tmp0_ = FALSE;
	gchar* result;
	g_return_val_if_fail (GEARY_IMAP_IS_FETCH_BODY_DATA_SPECIFIER (self), NULL);
	if (is_request) {
		_tmp0_ = self->priv->subset_count >= 0;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		gchar* _tmp1_ = NULL;
		gchar* _tmp4_;
		if (self->priv->subset_start < 0) {
			gchar* _tmp2_;
			_tmp2_ = g_strdup ("");
			_g_free0 (_tmp1_);
			_tmp1_ = _tmp2_;
		} else {
			gchar* _tmp3_;
			_tmp3_ = g_strdup_printf ("<%d.%d>", self->priv->subset_start, self->priv->subset_count);
			_g_free0 (_tmp1_);
			_tmp1_ = _tmp3_;
		}
		_tmp4_ = _tmp1_;
		_tmp1_ = NULL;
		result = _tmp4_;
		_g_free0 (_tmp1_);
		return result;
	} else {
		gchar* _tmp5_ = NULL;
		gchar* _tmp8_;
		if (self->priv->subset_start < 0) {
			gchar* _tmp6_;
			_tmp6_ = g_strdup ("");
			_g_free0 (_tmp5_);
			_tmp5_ = _tmp6_;
		} else {
			gchar* _tmp7_;
			_tmp7_ = g_strdup_printf ("<%d>", self->priv->subset_start);
			_g_free0 (_tmp5_);
			_tmp5_ = _tmp7_;
		}
		_tmp8_ = _tmp5_;
		_tmp5_ = NULL;
		result = _tmp8_;
		_g_free0 (_tmp5_);
		return result;
	}
}

/**
     * Returns true if the {@link StringParameter} is formatted like a
     * {@link FetchBodyDataSpecifier}.
     *
     * This method doesn't do a //full// test.  It's possible for {@link deserialize_response} to
     * throw an exception if this method returns true.  This method should be used for simple
     * identification when parsing and then catch the exception as the final word on validity.
     *
     * @see deserialize_response
     */
gboolean
geary_imap_fetch_body_data_specifier_is_fetch_body_data_specifier (GearyImapStringParameter* stringp)
{
	gchar* strd = NULL;
	gchar* _tmp0_;
	gchar* _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	gboolean _tmp4_ = FALSE;
	const gchar* _tmp5_;
	gboolean result;
	g_return_val_if_fail (GEARY_IMAP_IS_STRING_PARAMETER (stringp), FALSE);
	_tmp0_ = geary_imap_string_parameter_as_lower (stringp);
	_tmp1_ = _tmp0_;
	_tmp2_ = string_strip (_tmp1_);
	_tmp3_ = _tmp2_;
	_g_free0 (_tmp1_);
	strd = _tmp3_;
	_tmp5_ = strd;
	if (g_str_has_prefix (_tmp5_, "body[")) {
		_tmp4_ = TRUE;
	} else {
		const gchar* _tmp6_;
		_tmp6_ = strd;
		_tmp4_ = g_str_has_prefix (_tmp6_, "body.peek[");
	}
	result = _tmp4_;
	_g_free0 (strd);
	return result;
}

/**
     * Attempts to convert a {@link StringParameter} into a {@link FetchBodyDataSpecifier}.
     *
     * This will ''only'' convert responses from an IMAP server.  The request version of the
     * specifier has optional parameters not parsed here.  There currently is no
     * deserialize_request() version of this method.
     *
     * If any portion of the StringParameter doesn't look like a FETCH BODY data specifier,
     * an {@link ImapError.PARSE_ERROR} is thrown.
     */
static gchar*
string_replace (const gchar* self,
                const gchar* old,
                const gchar* replacement)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	GError* _inner_error0_ = NULL;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (old != NULL, NULL);
	g_return_val_if_fail (replacement != NULL, NULL);
	if ((*((gchar*) self)) == '\0') {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = (*((gchar*) old)) == '\0';
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = g_strcmp0 (old, replacement) == 0;
	}
	if (_tmp0_) {
		gchar* _tmp2_;
		_tmp2_ = g_strdup (self);
		result = _tmp2_;
		return result;
	}
	{
		GRegex* regex = NULL;
		gchar* _tmp3_;
		gchar* _tmp4_;
		GRegex* _tmp5_;
		GRegex* _tmp6_;
		gchar* _tmp7_ = NULL;
		GRegex* _tmp8_;
		gchar* _tmp9_;
		gchar* _tmp10_;
		_tmp3_ = g_regex_escape_string (old, -1);
		_tmp4_ = _tmp3_;
		_tmp5_ = g_regex_new (_tmp4_, 0, 0, &_inner_error0_);
		_tmp6_ = _tmp5_;
		_g_free0 (_tmp4_);
		regex = _tmp6_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			if (_inner_error0_->domain == G_REGEX_ERROR) {
				goto __catch0_g_regex_error;
			}
			g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
			g_clear_error (&_inner_error0_);
			return NULL;
		}
		_tmp8_ = regex;
		_tmp9_ = g_regex_replace_literal (_tmp8_, self, (gssize) -1, 0, replacement, 0, &_inner_error0_);
		_tmp7_ = _tmp9_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_regex_unref0 (regex);
			if (_inner_error0_->domain == G_REGEX_ERROR) {
				goto __catch0_g_regex_error;
			}
			g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
			g_clear_error (&_inner_error0_);
			return NULL;
		}
		_tmp10_ = _tmp7_;
		_tmp7_ = NULL;
		result = _tmp10_;
		_g_free0 (_tmp7_);
		_g_regex_unref0 (regex);
		return result;
	}
	goto __finally0;
	__catch0_g_regex_error:
	{
		g_clear_error (&_inner_error0_);
		g_assert_not_reached ();
	}
	__finally0:
	g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
	g_clear_error (&_inner_error0_);
	return NULL;
}

static gboolean
string_contains (const gchar* self,
                 const gchar* needle)
{
	gchar* _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (needle != NULL, FALSE);
	_tmp0_ = strstr ((gchar*) self, (gchar*) needle);
	result = _tmp0_ != NULL;
	return result;
}

static void
_vala_array_add6 (gint* * array,
                  gint* length,
                  gint* size,
                  gint value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (gint, *array, *size);
	}
	(*array)[(*length)++] = value;
}

GearyImapFetchBodyDataSpecifier*
geary_imap_fetch_body_data_specifier_deserialize_response (GearyImapStringParameter* stringp,
                                                           GError** error)
{
	gchar* strd = NULL;
	gchar* _tmp0_;
	gchar* _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	const gchar* section_string = NULL;
	const gchar* octet_string = NULL;
	gchar* section_chars = NULL;
	const gchar* _tmp6_;
	gint _tmp7_;
	gint _tmp8_;
	gchar* _tmp9_;
	gint section_chars_length1;
	gint _section_chars_size_;
	gchar* octet_chars = NULL;
	const gchar* _tmp10_;
	gint _tmp11_;
	gint _tmp12_;
	gchar* _tmp13_;
	gint octet_chars_length1;
	gint _octet_chars_size_;
	gint count = 0;
	const gchar* _tmp14_;
	gchar* _tmp15_;
	gint _tmp15__length1;
	gchar* _tmp16_;
	gint _tmp16__length1;
	gchar* part_chars = NULL;
	const gchar* _tmp24_;
	gint _tmp25_;
	gint _tmp26_;
	gchar* _tmp27_;
	gint part_chars_length1;
	gint _part_chars_size_;
	gchar* fields_chars = NULL;
	const gchar* _tmp28_;
	gint _tmp29_;
	gint _tmp30_;
	gchar* _tmp31_;
	gint fields_chars_length1;
	gint _fields_chars_size_;
	const gchar* part_string = NULL;
	const gchar* fields_string = NULL;
	const gchar* _tmp32_;
	GString* section_part_builder = NULL;
	GString* _tmp43_;
	gint* part_number = NULL;
	gint part_number_length1;
	gint _part_number_size_;
	gchar** part_number_tokens = NULL;
	const gchar* _tmp44_;
	gchar** _tmp45_;
	gchar** _tmp46_;
	gint part_number_tokens_length1;
	gint _part_number_tokens_size_;
	gchar** _tmp47_;
	gint _tmp47__length1;
	GearyImapFetchBodyDataSpecifierSectionPart section_part = 0;
	GString* _tmp65_;
	const gchar* _tmp66_;
	gchar* _tmp67_;
	gchar* _tmp68_;
	GearyImapFetchBodyDataSpecifierSectionPart _tmp69_;
	gchar** field_names = NULL;
	gint field_names_length1;
	gint _field_names_size_;
	const gchar* _tmp70_;
	gint subset_start = 0;
	const gchar* _tmp77_;
	gint* _tmp90_;
	gint _tmp90__length1;
	gchar** _tmp91_;
	gint _tmp91__length1;
	GearyImapFetchBodyDataSpecifier* _tmp92_;
	GError* _inner_error0_ = NULL;
	GearyImapFetchBodyDataSpecifier* result;
	g_return_val_if_fail (GEARY_IMAP_IS_STRING_PARAMETER (stringp), NULL);
	_tmp0_ = geary_imap_string_parameter_as_lower (stringp);
	_tmp1_ = _tmp0_;
	_tmp2_ = string_replace (_tmp1_, "\"", "");
	_tmp3_ = _tmp2_;
	_tmp4_ = string_strip (_tmp3_);
	_tmp5_ = _tmp4_;
	_g_free0 (_tmp3_);
	_g_free0 (_tmp1_);
	strd = _tmp5_;
	_tmp6_ = strd;
	_tmp7_ = strlen (_tmp6_);
	_tmp8_ = _tmp7_;
	_tmp9_ = g_new0 (gchar, _tmp8_);
	section_chars = _tmp9_;
	section_chars_length1 = _tmp8_;
	_section_chars_size_ = section_chars_length1;
	_tmp10_ = strd;
	_tmp11_ = strlen (_tmp10_);
	_tmp12_ = _tmp11_;
	_tmp13_ = g_new0 (gchar, _tmp12_);
	octet_chars = _tmp13_;
	octet_chars_length1 = _tmp12_;
	_octet_chars_size_ = octet_chars_length1;
	_tmp14_ = strd;
	_tmp15_ = section_chars;
	_tmp15__length1 = section_chars_length1;
	_tmp16_ = octet_chars;
	_tmp16__length1 = octet_chars_length1;
	count = sscanf (_tmp14_, "body[%[^]]]%s", _tmp15_, _tmp16_);
	switch (count) {
		case 1:
		{
			gchar* _tmp17_;
			gint _tmp17__length1;
			_tmp17_ = section_chars;
			_tmp17__length1 = section_chars_length1;
			section_string = (const gchar*) _tmp17_;
			octet_string = NULL;
			break;
		}
		case 2:
		{
			gchar* _tmp18_;
			gint _tmp18__length1;
			gchar* _tmp19_;
			gint _tmp19__length1;
			_tmp18_ = section_chars;
			_tmp18__length1 = section_chars_length1;
			section_string = (const gchar*) _tmp18_;
			_tmp19_ = octet_chars;
			_tmp19__length1 = octet_chars_length1;
			octet_string = (const gchar*) _tmp19_;
			break;
		}
		default:
		{
			gchar* _tmp20_;
			gchar* _tmp21_;
			GError* _tmp22_;
			GError* _tmp23_;
			_tmp20_ = geary_imap_parameter_to_string (G_TYPE_CHECK_INSTANCE_CAST (stringp, GEARY_IMAP_TYPE_PARAMETER, GearyImapParameter));
			_tmp21_ = _tmp20_;
			_tmp22_ = g_error_new (GEARY_IMAP_ERROR, GEARY_IMAP_ERROR_PARSE_ERROR, "%s is not a FETCH body data type %d", _tmp21_, count);
			_tmp23_ = _tmp22_;
			_g_free0 (_tmp21_);
			_inner_error0_ = _tmp23_;
			if (_inner_error0_->domain == GEARY_IMAP_ERROR) {
				g_propagate_error (error, _inner_error0_);
				octet_chars = (g_free (octet_chars), NULL);
				section_chars = (g_free (section_chars), NULL);
				_g_free0 (strd);
				return NULL;
			} else {
				octet_chars = (g_free (octet_chars), NULL);
				section_chars = (g_free (section_chars), NULL);
				_g_free0 (strd);
				g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
				g_clear_error (&_inner_error0_);
				return NULL;
			}
		}
	}
	_tmp24_ = section_string;
	_tmp25_ = strlen (_tmp24_);
	_tmp26_ = _tmp25_;
	_tmp27_ = g_new0 (gchar, _tmp26_);
	part_chars = _tmp27_;
	part_chars_length1 = _tmp26_;
	_part_chars_size_ = part_chars_length1;
	_tmp28_ = section_string;
	_tmp29_ = strlen (_tmp28_);
	_tmp30_ = _tmp29_;
	_tmp31_ = g_new0 (gchar, _tmp30_);
	fields_chars = _tmp31_;
	fields_chars_length1 = _tmp30_;
	_fields_chars_size_ = fields_chars_length1;
	_tmp32_ = section_string;
	if (string_contains (_tmp32_, "(")) {
		const gchar* _tmp33_;
		gchar* _tmp34_;
		gint _tmp34__length1;
		gchar* _tmp35_;
		gint _tmp35__length1;
		gchar* _tmp40_;
		gint _tmp40__length1;
		gchar* _tmp41_;
		gint _tmp41__length1;
		_tmp33_ = section_string;
		_tmp34_ = part_chars;
		_tmp34__length1 = part_chars_length1;
		_tmp35_ = fields_chars;
		_tmp35__length1 = fields_chars_length1;
		if (sscanf (_tmp33_, "%[^(](%[^)])", _tmp34_, _tmp35_) != 2) {
			gchar* _tmp36_;
			gchar* _tmp37_;
			GError* _tmp38_;
			GError* _tmp39_;
			_tmp36_ = geary_imap_parameter_to_string (G_TYPE_CHECK_INSTANCE_CAST (stringp, GEARY_IMAP_TYPE_PARAMETER, GearyImapParameter));
			_tmp37_ = _tmp36_;
			_tmp38_ = g_error_new (GEARY_IMAP_ERROR, GEARY_IMAP_ERROR_PARSE_ERROR, "%s: malformed part/header names", _tmp37_);
			_tmp39_ = _tmp38_;
			_g_free0 (_tmp37_);
			_inner_error0_ = _tmp39_;
			if (_inner_error0_->domain == GEARY_IMAP_ERROR) {
				g_propagate_error (error, _inner_error0_);
				fields_chars = (g_free (fields_chars), NULL);
				part_chars = (g_free (part_chars), NULL);
				octet_chars = (g_free (octet_chars), NULL);
				section_chars = (g_free (section_chars), NULL);
				_g_free0 (strd);
				return NULL;
			} else {
				fields_chars = (g_free (fields_chars), NULL);
				part_chars = (g_free (part_chars), NULL);
				octet_chars = (g_free (octet_chars), NULL);
				section_chars = (g_free (section_chars), NULL);
				_g_free0 (strd);
				g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
				g_clear_error (&_inner_error0_);
				return NULL;
			}
		}
		_tmp40_ = part_chars;
		_tmp40__length1 = part_chars_length1;
		part_string = (const gchar*) _tmp40_;
		_tmp41_ = fields_chars;
		_tmp41__length1 = fields_chars_length1;
		fields_string = (const gchar*) _tmp41_;
	} else {
		const gchar* _tmp42_;
		_tmp42_ = section_string;
		part_string = _tmp42_;
		fields_string = NULL;
	}
	_tmp43_ = g_string_new ("");
	section_part_builder = _tmp43_;
	part_number = NULL;
	part_number_length1 = 0;
	_part_number_size_ = part_number_length1;
	_tmp44_ = part_string;
	_tmp46_ = _tmp45_ = g_strsplit (_tmp44_, ".", 0);
	part_number_tokens = _tmp46_;
	part_number_tokens_length1 = _vala_array_length (_tmp45_);
	_part_number_tokens_size_ = part_number_tokens_length1;
	_tmp47_ = part_number_tokens;
	_tmp47__length1 = part_number_tokens_length1;
	if (_tmp47_ != NULL) {
		gboolean no_more = FALSE;
		no_more = FALSE;
		{
			gint ctr = 0;
			ctr = 0;
			{
				gboolean _tmp48_ = FALSE;
				_tmp48_ = TRUE;
				while (TRUE) {
					gchar** _tmp50_;
					gint _tmp50__length1;
					gchar* token = NULL;
					gchar** _tmp51_;
					gint _tmp51__length1;
					const gchar* _tmp52_;
					gchar* _tmp53_;
					gboolean _tmp54_ = FALSE;
					if (!_tmp48_) {
						gint _tmp49_;
						_tmp49_ = ctr;
						ctr = _tmp49_ + 1;
					}
					_tmp48_ = FALSE;
					_tmp50_ = part_number_tokens;
					_tmp50__length1 = part_number_tokens_length1;
					if (!(ctr < _tmp50__length1)) {
						break;
					}
					_tmp51_ = part_number_tokens;
					_tmp51__length1 = part_number_tokens_length1;
					_tmp52_ = _tmp51_[ctr];
					_tmp53_ = g_strdup (_tmp52_);
					token = _tmp53_;
					if (!no_more) {
						const gchar* _tmp55_;
						_tmp55_ = token;
						_tmp54_ = geary_ascii_is_numeric (_tmp55_);
					} else {
						_tmp54_ = FALSE;
					}
					if (_tmp54_) {
						gint* _tmp56_;
						gint _tmp56__length1;
						const gchar* _tmp58_;
						_tmp56_ = part_number;
						_tmp56__length1 = part_number_length1;
						if (_tmp56_ == NULL) {
							gint* _tmp57_;
							_tmp57_ = g_new0 (gint, 0);
							part_number = (g_free (part_number), NULL);
							part_number = _tmp57_;
							part_number_length1 = 0;
							_part_number_size_ = part_number_length1;
						}
						_tmp58_ = token;
						_vala_array_add6 (&part_number, &part_number_length1, &_part_number_size_, atoi (_tmp58_));
					} else {
						GString* _tmp59_;
						const gchar* _tmp60_;
						gchar** _tmp61_;
						gint _tmp61__length1;
						no_more = TRUE;
						_tmp59_ = section_part_builder;
						_tmp60_ = token;
						g_string_append (_tmp59_, _tmp60_);
						_tmp61_ = part_number_tokens;
						_tmp61__length1 = part_number_tokens_length1;
						if (ctr < (_tmp61__length1 - 1)) {
							GString* _tmp62_;
							_tmp62_ = section_part_builder;
							g_string_append (_tmp62_, ".");
						}
					}
					_g_free0 (token);
				}
			}
		}
	} else {
		GString* _tmp63_;
		const gchar* _tmp64_;
		_tmp63_ = section_part_builder;
		_tmp64_ = part_string;
		g_string_append (_tmp63_, _tmp64_);
	}
	_tmp65_ = section_part_builder;
	_tmp66_ = _tmp65_->str;
	_tmp67_ = string_strip (_tmp66_);
	_tmp68_ = _tmp67_;
	_tmp69_ = geary_imap_fetch_body_data_specifier_section_part_deserialize (_tmp68_, &_inner_error0_);
	_g_free0 (_tmp68_);
	section_part = _tmp69_;
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		if (_inner_error0_->domain == GEARY_IMAP_ERROR) {
			g_propagate_error (error, _inner_error0_);
			part_number_tokens = (_vala_array_free (part_number_tokens, part_number_tokens_length1, (GDestroyNotify) g_free), NULL);
			part_number = (g_free (part_number), NULL);
			_g_string_free0 (section_part_builder);
			fields_chars = (g_free (fields_chars), NULL);
			part_chars = (g_free (part_chars), NULL);
			octet_chars = (g_free (octet_chars), NULL);
			section_chars = (g_free (section_chars), NULL);
			_g_free0 (strd);
			return NULL;
		} else {
			part_number_tokens = (_vala_array_free (part_number_tokens, part_number_tokens_length1, (GDestroyNotify) g_free), NULL);
			part_number = (g_free (part_number), NULL);
			_g_string_free0 (section_part_builder);
			fields_chars = (g_free (fields_chars), NULL);
			part_chars = (g_free (part_chars), NULL);
			octet_chars = (g_free (octet_chars), NULL);
			section_chars = (g_free (section_chars), NULL);
			_g_free0 (strd);
			g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
			g_clear_error (&_inner_error0_);
			return NULL;
		}
	}
	field_names = NULL;
	field_names_length1 = 0;
	_field_names_size_ = field_names_length1;
	_tmp70_ = fields_string;
	if (_tmp70_ != NULL) {
		const gchar* _tmp71_;
		gchar* _tmp72_;
		gchar* _tmp73_;
		gchar** _tmp74_;
		gchar** _tmp75_;
		gchar** _tmp76_;
		gint _tmp76__length1;
		_tmp71_ = fields_string;
		_tmp72_ = string_strip (_tmp71_);
		_tmp73_ = _tmp72_;
		_tmp75_ = _tmp74_ = g_strsplit (_tmp73_, " ", 0);
		field_names = (_vala_array_free (field_names, field_names_length1, (GDestroyNotify) g_free), NULL);
		field_names = _tmp75_;
		field_names_length1 = _vala_array_length (_tmp74_);
		_field_names_size_ = field_names_length1;
		_g_free0 (_tmp73_);
		_tmp76_ = field_names;
		_tmp76__length1 = field_names_length1;
		if (_tmp76__length1 == 0) {
			field_names = (_vala_array_free (field_names, field_names_length1, (GDestroyNotify) g_free), NULL);
			field_names = NULL;
			field_names_length1 = 0;
			_field_names_size_ = field_names_length1;
		}
	}
	subset_start = -1;
	_tmp77_ = octet_string;
	if (!geary_string_is_empty (_tmp77_)) {
		const gchar* _tmp78_;
		gint _tmp79_ = 0;
		gint _tmp80_;
		_tmp78_ = octet_string;
		_tmp80_ = sscanf (_tmp78_, "<%d>", &_tmp79_);
		subset_start = _tmp79_;
		if (_tmp80_ != 1) {
			const gchar* _tmp81_;
			gchar* _tmp82_;
			gchar* _tmp83_;
			GError* _tmp84_;
			GError* _tmp85_;
			_tmp81_ = octet_string;
			_tmp82_ = geary_imap_parameter_to_string (G_TYPE_CHECK_INSTANCE_CAST (stringp, GEARY_IMAP_TYPE_PARAMETER, GearyImapParameter));
			_tmp83_ = _tmp82_;
			_tmp84_ = g_error_new (GEARY_IMAP_ERROR, GEARY_IMAP_ERROR_PARSE_ERROR, "Improperly formed octet \"%s\" in %s", _tmp81_, _tmp83_);
			_tmp85_ = _tmp84_;
			_g_free0 (_tmp83_);
			_inner_error0_ = _tmp85_;
			if (_inner_error0_->domain == GEARY_IMAP_ERROR) {
				g_propagate_error (error, _inner_error0_);
				field_names = (_vala_array_free (field_names, field_names_length1, (GDestroyNotify) g_free), NULL);
				part_number_tokens = (_vala_array_free (part_number_tokens, part_number_tokens_length1, (GDestroyNotify) g_free), NULL);
				part_number = (g_free (part_number), NULL);
				_g_string_free0 (section_part_builder);
				fields_chars = (g_free (fields_chars), NULL);
				part_chars = (g_free (part_chars), NULL);
				octet_chars = (g_free (octet_chars), NULL);
				section_chars = (g_free (section_chars), NULL);
				_g_free0 (strd);
				return NULL;
			} else {
				field_names = (_vala_array_free (field_names, field_names_length1, (GDestroyNotify) g_free), NULL);
				part_number_tokens = (_vala_array_free (part_number_tokens, part_number_tokens_length1, (GDestroyNotify) g_free), NULL);
				part_number = (g_free (part_number), NULL);
				_g_string_free0 (section_part_builder);
				fields_chars = (g_free (fields_chars), NULL);
				part_chars = (g_free (part_chars), NULL);
				octet_chars = (g_free (octet_chars), NULL);
				section_chars = (g_free (section_chars), NULL);
				_g_free0 (strd);
				g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
				g_clear_error (&_inner_error0_);
				return NULL;
			}
		}
		if (subset_start < 0) {
			gchar* _tmp86_;
			gchar* _tmp87_;
			GError* _tmp88_;
			GError* _tmp89_;
			_tmp86_ = geary_imap_parameter_to_string (G_TYPE_CHECK_INSTANCE_CAST (stringp, GEARY_IMAP_TYPE_PARAMETER, GearyImapParameter));
			_tmp87_ = _tmp86_;
			_tmp88_ = g_error_new (GEARY_IMAP_ERROR, GEARY_IMAP_ERROR_PARSE_ERROR, "Invalid octet count %d in %s", subset_start, _tmp87_);
			_tmp89_ = _tmp88_;
			_g_free0 (_tmp87_);
			_inner_error0_ = _tmp89_;
			if (_inner_error0_->domain == GEARY_IMAP_ERROR) {
				g_propagate_error (error, _inner_error0_);
				field_names = (_vala_array_free (field_names, field_names_length1, (GDestroyNotify) g_free), NULL);
				part_number_tokens = (_vala_array_free (part_number_tokens, part_number_tokens_length1, (GDestroyNotify) g_free), NULL);
				part_number = (g_free (part_number), NULL);
				_g_string_free0 (section_part_builder);
				fields_chars = (g_free (fields_chars), NULL);
				part_chars = (g_free (part_chars), NULL);
				octet_chars = (g_free (octet_chars), NULL);
				section_chars = (g_free (section_chars), NULL);
				_g_free0 (strd);
				return NULL;
			} else {
				field_names = (_vala_array_free (field_names, field_names_length1, (GDestroyNotify) g_free), NULL);
				part_number_tokens = (_vala_array_free (part_number_tokens, part_number_tokens_length1, (GDestroyNotify) g_free), NULL);
				part_number = (g_free (part_number), NULL);
				_g_string_free0 (section_part_builder);
				fields_chars = (g_free (fields_chars), NULL);
				part_chars = (g_free (part_chars), NULL);
				octet_chars = (g_free (octet_chars), NULL);
				section_chars = (g_free (section_chars), NULL);
				_g_free0 (strd);
				g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
				g_clear_error (&_inner_error0_);
				return NULL;
			}
		}
	}
	_tmp90_ = part_number;
	_tmp90__length1 = part_number_length1;
	_tmp91_ = field_names;
	_tmp91__length1 = field_names_length1;
	_tmp92_ = geary_imap_fetch_body_data_specifier_new_response (section_part, _tmp90_, _tmp90__length1, subset_start, _tmp91_, _tmp91__length1);
	result = _tmp92_;
	field_names = (_vala_array_free (field_names, field_names_length1, (GDestroyNotify) g_free), NULL);
	part_number_tokens = (_vala_array_free (part_number_tokens, part_number_tokens_length1, (GDestroyNotify) g_free), NULL);
	part_number = (g_free (part_number), NULL);
	_g_string_free0 (section_part_builder);
	fields_chars = (g_free (fields_chars), NULL);
	part_chars = (g_free (part_chars), NULL);
	octet_chars = (g_free (octet_chars), NULL);
	section_chars = (g_free (section_chars), NULL);
	_g_free0 (strd);
	return result;
}

/**
     * Omit the space between "header.fields" and the list of email headers.
     *
     * Some servers in the wild don't recognize the FETCH command if this space is present, and
     * so this allows for it to be omitted when serializing the request.  This appears to be in
     * violation of the IMAP specification, but these servers still exist.
     *
     * This should be used with care.  If enabled, a lot of servers will not accept the FETCH
     * command for the same reason (unrecognized request).
     *
     * Once set, this cannot be cleared.  To do so, create a new {@link FetchBodyDataSpecifier}.
     *
     * See [[http://tools.ietf.org/html/rfc3501#section-6.4.5]]
     * and [[https://bugzilla.gnome.org/show_bug.cgi?id=714902]]
     */
void
geary_imap_fetch_body_data_specifier_omit_request_header_fields_space (GearyImapFetchBodyDataSpecifier* self)
{
	g_return_if_fail (GEARY_IMAP_IS_FETCH_BODY_DATA_SPECIFIER (self));
	geary_imap_fetch_body_data_specifier_set_request_header_fields_space (self, FALSE);
}

/**
     * {@link FetchBodyDataSpecifier}s are considered equal if they're serialized responses are
     * equal.
     *
     * This is because it's perceived that a corresponding request and response specifier may be
     * compared, but because of syntactic differences, are not strictly textually equal.  By
     * comparing how each specifier appears in its response format (which is a subset of the
     * parameters available in a request), a comparison is available.
     */
static gboolean
geary_imap_fetch_body_data_specifier_real_equal_to (GeeHashable* base,
                                                    GearyImapFetchBodyDataSpecifier* other)
{
	GearyImapFetchBodyDataSpecifier * self;
	const gchar* _tmp0_;
	const gchar* _tmp1_;
	gboolean result;
	self = G_TYPE_CHECK_INSTANCE_CAST (base, GEARY_IMAP_TYPE_FETCH_BODY_DATA_SPECIFIER, GearyImapFetchBodyDataSpecifier);
	g_return_val_if_fail (GEARY_IMAP_IS_FETCH_BODY_DATA_SPECIFIER (other), FALSE);
	if (self == other) {
		result = TRUE;
		return result;
	}
	_tmp0_ = self->priv->hashable;
	_tmp1_ = other->priv->hashable;
	result = g_strcmp0 (_tmp0_, _tmp1_) == 0;
	return result;
}

static guint
geary_imap_fetch_body_data_specifier_real_hash (GeeHashable* base)
{
	GearyImapFetchBodyDataSpecifier * self;
	GHashFunc _tmp0_;
	const gchar* _tmp1_;
	guint result;
	self = G_TYPE_CHECK_INSTANCE_CAST (base, GEARY_IMAP_TYPE_FETCH_BODY_DATA_SPECIFIER, GearyImapFetchBodyDataSpecifier);
	_tmp0_ = g_str_hash;
	_tmp1_ = self->priv->hashable;
	result = _tmp0_ (_tmp1_);
	return result;
}

gchar*
geary_imap_fetch_body_data_specifier_to_string (GearyImapFetchBodyDataSpecifier* self)
{
	gchar* _tmp0_;
	gchar* result;
	g_return_val_if_fail (GEARY_IMAP_IS_FETCH_BODY_DATA_SPECIFIER (self), NULL);
	_tmp0_ = geary_imap_fetch_body_data_specifier_serialize_request (self);
	result = _tmp0_;
	return result;
}

static void
geary_imap_fetch_body_data_specifier_class_init (GearyImapFetchBodyDataSpecifierClass * klass,
                                                 gpointer klass_data)
{
	geary_imap_fetch_body_data_specifier_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &GearyImapFetchBodyDataSpecifier_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_geary_imap_fetch_body_data_specifier_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_geary_imap_fetch_body_data_specifier_set_property;
	G_OBJECT_CLASS (klass)->finalize = geary_imap_fetch_body_data_specifier_finalize;
	/**
	     * The {@link SectionPart} for this FETCH BODY specifier.
	     *
	     * This is exposed to detect a server bug; other fields in this object could be exposed as
	     * well in the future, if necessary.
	     */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_PROPERTY, geary_imap_fetch_body_data_specifier_properties[GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_PROPERTY] = g_param_spec_enum ("section-part", "section-part", "section-part", GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_TYPE_SECTION_PART, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	/**
	     * When false, indicates that the FETCH BODY specifier is using a hack to operate with
	     * non-conformant servers.
	     *
	     * This is exposed to detect a server bug; other fields in this object could be exposed as
	     * well in the future, if necessary.
	     *
	     * @see omit_request_header_fields_space
	     */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_REQUEST_HEADER_FIELDS_SPACE_PROPERTY, geary_imap_fetch_body_data_specifier_properties[GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_REQUEST_HEADER_FIELDS_SPACE_PROPERTY] = g_param_spec_boolean ("request-header-fields-space", "request-header-fields-space", "request-header-fields-space", TRUE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
}

static void
geary_imap_fetch_body_data_specifier_gee_hashable_interface_init (GeeHashableIface * iface,
                                                                  gpointer iface_data)
{
	geary_imap_fetch_body_data_specifier_gee_hashable_parent_iface = g_type_interface_peek_parent (iface);
	iface->equal_to = (gboolean (*) (GeeHashable*, gconstpointer)) geary_imap_fetch_body_data_specifier_real_equal_to;
	iface->hash = (guint (*) (GeeHashable*)) geary_imap_fetch_body_data_specifier_real_hash;
}

static void
geary_imap_fetch_body_data_specifier_instance_init (GearyImapFetchBodyDataSpecifier * self,
                                                    gpointer klass)
{
	self->priv = geary_imap_fetch_body_data_specifier_get_instance_private (self);
	self->priv->_request_header_fields_space = TRUE;
}

static void
geary_imap_fetch_body_data_specifier_finalize (GObject * obj)
{
	GearyImapFetchBodyDataSpecifier * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GEARY_IMAP_TYPE_FETCH_BODY_DATA_SPECIFIER, GearyImapFetchBodyDataSpecifier);
	self->priv->part_number = (g_free (self->priv->part_number), NULL);
	_g_object_unref0 (self->priv->field_names);
	_g_free0 (self->priv->hashable);
	G_OBJECT_CLASS (geary_imap_fetch_body_data_specifier_parent_class)->finalize (obj);
}

/**
 * A symbolic representation of IMAP FETCH's BODY section parameter.
 *
 * This is only used with {@link FetchCommand}.  Most IMAP FETCH calls can be achieved with
 * plain {@link FetchDataSpecifier}s.  Some cannot, however, and this more complicated
 * specifier must be used.
 *
 * A fully-qualified specifier looks something like this for requests:
 *
 * BODY[part_number.section_part]<subset_start.subset_count>
 *
 * or, when headers are specified:
 *
 * BODY[part_number.section_part (header_fields)]<subset_start.subset_count>
 *
 * There is also a .peek variant.
 *
 * For responses, a fully-qualified specifier looks something like this:
 *
 * BODY[part_number.section_part (header_fields)]<subset_start>
 *
 * There is no .peek variant in responses.
 *
 * Note that Gmail apparently doesn't like BODY[1.TEXT] and instead must be specified with
 * BODY[1].  Also note that there's a PEEK variant that will not add the /Seen flag to the message.
 *
 * See [[http://tools.ietf.org/html/rfc3501#section-6.4.5]], specifically section on
 * BODY[<section>]<<partial>>, and [[http://tools.ietf.org/html/rfc3501#section-7.4.2]],
 * specifically section on BODY[<section>]<<origin octet>>.
 *
 * @see FetchDataSpecifier
 */
 G_GNUC_NO_INLINE static GType
geary_imap_fetch_body_data_specifier_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GearyImapFetchBodyDataSpecifierClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) geary_imap_fetch_body_data_specifier_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GearyImapFetchBodyDataSpecifier), 0, (GInstanceInitFunc) geary_imap_fetch_body_data_specifier_instance_init, NULL };
	static const GInterfaceInfo gee_hashable_info = { (GInterfaceInitFunc) geary_imap_fetch_body_data_specifier_gee_hashable_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	GType geary_imap_fetch_body_data_specifier_type_id;
	geary_imap_fetch_body_data_specifier_type_id = g_type_register_static (GEARY_TYPE_BASE_OBJECT, "GearyImapFetchBodyDataSpecifier", &g_define_type_info, 0);
	g_type_add_interface_static (geary_imap_fetch_body_data_specifier_type_id, GEE_TYPE_HASHABLE, &gee_hashable_info);
	GearyImapFetchBodyDataSpecifier_private_offset = g_type_add_instance_private (geary_imap_fetch_body_data_specifier_type_id, sizeof (GearyImapFetchBodyDataSpecifierPrivate));
	return geary_imap_fetch_body_data_specifier_type_id;
}

GType
geary_imap_fetch_body_data_specifier_get_type (void)
{
	static gsize geary_imap_fetch_body_data_specifier_type_id__once = 0;
	if (g_once_init_enter (&geary_imap_fetch_body_data_specifier_type_id__once)) {
		GType geary_imap_fetch_body_data_specifier_type_id;
		geary_imap_fetch_body_data_specifier_type_id = geary_imap_fetch_body_data_specifier_get_type_once ();
		g_once_init_leave (&geary_imap_fetch_body_data_specifier_type_id__once, geary_imap_fetch_body_data_specifier_type_id);
	}
	return geary_imap_fetch_body_data_specifier_type_id__once;
}

static void
_vala_geary_imap_fetch_body_data_specifier_get_property (GObject * object,
                                                         guint property_id,
                                                         GValue * value,
                                                         GParamSpec * pspec)
{
	GearyImapFetchBodyDataSpecifier * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GEARY_IMAP_TYPE_FETCH_BODY_DATA_SPECIFIER, GearyImapFetchBodyDataSpecifier);
	switch (property_id) {
		case GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_PROPERTY:
		g_value_set_enum (value, geary_imap_fetch_body_data_specifier_get_section_part (self));
		break;
		case GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_REQUEST_HEADER_FIELDS_SPACE_PROPERTY:
		g_value_set_boolean (value, geary_imap_fetch_body_data_specifier_get_request_header_fields_space (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_geary_imap_fetch_body_data_specifier_set_property (GObject * object,
                                                         guint property_id,
                                                         const GValue * value,
                                                         GParamSpec * pspec)
{
	GearyImapFetchBodyDataSpecifier * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GEARY_IMAP_TYPE_FETCH_BODY_DATA_SPECIFIER, GearyImapFetchBodyDataSpecifier);
	switch (property_id) {
		case GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_SECTION_PART_PROPERTY:
		geary_imap_fetch_body_data_specifier_set_section_part (self, g_value_get_enum (value));
		break;
		case GEARY_IMAP_FETCH_BODY_DATA_SPECIFIER_REQUEST_HEADER_FIELDS_SPACE_PROPERTY:
		geary_imap_fetch_body_data_specifier_set_request_header_fields_space (self, g_value_get_boolean (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_array_destroy (gpointer array,
                     gssize array_length,
                     GDestroyNotify destroy_func)
{
	if ((array != NULL) && (destroy_func != NULL)) {
		gssize i;
		for (i = 0; i < array_length; i = i + 1) {
			if (((gpointer*) array)[i] != NULL) {
				destroy_func (((gpointer*) array)[i]);
			}
		}
	}
}

static void
_vala_array_free (gpointer array,
                  gssize array_length,
                  GDestroyNotify destroy_func)
{
	_vala_array_destroy (array, array_length, destroy_func);
	g_free (array);
}

static gssize
_vala_array_length (gpointer array)
{
	gssize length;
	length = 0;
	if (array) {
		while (((gpointer*) array)[length]) {
			length++;
		}
	}
	return length;
}

