static PyObject *bpy_bmlayercollection_new(BPy_BMLayerCollection *self, PyObject *args)
{
	const char *name = NULL;
	int index;
	CustomData *data;

	BPY_BM_CHECK_OBJ(self);

	if (!PyArg_ParseTuple(args, "|s:new", &name)) {
		return NULL;
	}

	data = bpy_bm_customdata_get(self->bm, self->htype);

	if (CustomData_layertype_is_singleton(self->type) &&
	    CustomData_has_layer(data, self->type))
	{
		PyErr_SetString(PyExc_ValueError,
		                "layers.new(): is a singleton, use verify() instead");
		return NULL;
	}

	if (name) {
		BM_data_layer_add_named(self->bm, data, self->type, name);
	}
	else {
		BM_data_layer_add(self->bm, data, self->type);
	}

	index = CustomData_number_of_layers(data, self->type) - 1;
	BLI_assert(index >= 0);

	return BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index);
}
static PyObject *bpy_bmlayercollection_items(BPy_BMLayerCollection *self)
{
	PyObject *ret;
	PyObject *item;
	int index;
	CustomData *data;
	int tot, i;

	BPY_BM_CHECK_OBJ(self);

	data = bpy_bm_customdata_get(self->bm, self->htype);
	index = CustomData_get_layer_index(data, self->type);
	tot = (index != -1) ? CustomData_number_of_layers(data, self->type) : 0;

	ret = PyList_New(tot);

	for (i = 0; tot-- > 0; index++) {
		item = PyTuple_New(2);
		PyTuple_SET_ITEMS(item,
		        PyUnicode_FromString(data->layers[index].name),
		        BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, i));
		PyList_SET_ITEM(ret, i++, item);
	}

	return ret;
}
static PyObject *bpy_bmlayercollection_get(BPy_BMLayerCollection *self, PyObject *args)
{
	const char *key;
	PyObject *def = Py_None;

	BPY_BM_CHECK_OBJ(self);

	if (!PyArg_ParseTuple(args, "s|O:get", &key, &def)) {
		return NULL;
	}
	else {
		CustomData *data;
		int index;

		data = bpy_bm_customdata_get(self->bm, self->htype);
		index = CustomData_get_named_layer_index(data, self->type, key); /* absolute index */

		if (index != -1) {
			index -= CustomData_get_layer_index(data, self->type); /* make relative */
			return BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index);
		}
	}

	return Py_INCREF(def), def;
}
static PyObject *bpy_bmlayercollection_items(BPy_BMLayerCollection *self)
{
	PyObject *ret;
	PyObject *item;
	int index;
	CustomData *data;

	BPY_BM_CHECK_OBJ(self);

	data = bpy_bm_customdata_get(self->bm, self->htype);
	index = CustomData_get_layer_index(data, self->type);

	ret = PyList_New(0);

	if (index != -1) {
		int tot = CustomData_number_of_layers(data, self->type);
		for ( ; tot-- > 0; index++) {
			item = BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index);
			PyList_Append(ret, item);
			Py_DECREF(item);
		}
	}

	return ret;
}
static PyObject *bpy_bmlayercollection_values(BPy_BMLayerCollection *self)
{
	PyObject *ret;
	PyObject *item;
	int index;
	CustomData *data;

	BPY_BM_CHECK_OBJ(self);

	data = bpy_bm_customdata_get(self->bm, self->htype);
	index = CustomData_get_layer_index(data, self->type);

	ret = PyList_New(0);

	if (index != -1) {
		int tot = CustomData_number_of_layers(data, self->type);
		for ( ; tot-- > 0; index++) {
			item = PyTuple_New(2);
			PyTuple_SET_ITEM(item, 0, PyUnicode_FromString(data->layers[index].name));
			PyTuple_SET_ITEM(item, 1, BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index));
			PyList_Append(ret, item);
			Py_DECREF(item);
		}
	}

	return ret;
}
static PyObject *bpy_bmlayercollection_active_get(BPy_BMLayerItem *self, void *UNUSED(flag))
{
	CustomData *data;
	int index;

	BPY_BM_CHECK_OBJ(self);

	data = bpy_bm_customdata_get(self->bm, self->htype);
	index = CustomData_get_active_layer(data, self->type);  /* type relative */

	if (index != -1) {
		return BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index);
	}
	else {
		Py_RETURN_NONE;
	}
}
static PyObject *bpy_bmlayercollection_subscript_int(BPy_BMLayerCollection *self, int keynum)
{
	Py_ssize_t len;
	BPY_BM_CHECK_OBJ(self);

	len = bpy_bmlayercollection_length(self);

	if (keynum < 0) keynum += len;
	if (keynum >= 0) {
		if (keynum < len) {
			return BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, keynum);
		}
	}

	PyErr_Format(PyExc_IndexError,
	             "BMLayerCollection[index]: index %d out of range", keynum);
	return NULL;
}
static PyObject *bpy_bmlayercollection_subscript_str(BPy_BMLayerCollection *self, const char *keyname)
{
	CustomData *data;
	int index;

	BPY_BM_CHECK_OBJ(self);

	data = bpy_bm_customdata_get(self->bm, self->htype);
	index = CustomData_get_named_layer(data, self->type, keyname);  /* type relative */

	if (index != -1) {
		return BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index);
	}
	else {
		PyErr_Format(PyExc_KeyError,
		             "BMLayerCollection[key]: key \"%.200s\" not found", keyname);
		return NULL;
	}
}
static PyObject *bpy_bmlayercollection_subscript_slice(BPy_BMLayerCollection *self, Py_ssize_t start, Py_ssize_t stop)
{
	Py_ssize_t len = bpy_bmlayercollection_length(self);
	int count = 0;

	PyObject *tuple;

	BPY_BM_CHECK_OBJ(self);

	if (start >= len) start = len - 1;
	if (stop  >= len) stop  = len - 1;

	tuple = PyTuple_New(stop - start);

	for (count = start; count < stop; count++) {
		PyTuple_SET_ITEM(tuple, count - start, BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, count));
	}

	return tuple;
}
static PyObject *bpy_bmlayercollection_verify(BPy_BMLayerCollection *self)
{
	int index;
	CustomData *data;

	BPY_BM_CHECK_OBJ(self);

	data = bpy_bm_customdata_get(self->bm, self->htype);

	index = CustomData_get_active_layer(data, self->type);  /* type relative */

	if (index == -1) {
		BM_data_layer_add(self->bm, data, self->type);
		index = 0;
	}

	BLI_assert(index >= 0);

	return BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index);
}
static PyObject *bpy_bmlayercollection_values(BPy_BMLayerCollection *self)
{
	PyObject *ret;
	PyObject *item;
	int index;
	CustomData *data;
	int tot, i;

	BPY_BM_CHECK_OBJ(self);

	data = bpy_bm_customdata_get(self->bm, self->htype);
	index = CustomData_get_layer_index(data, self->type);
	tot = (index != -1) ? CustomData_number_of_layers(data, self->type) : 0;

	ret = PyList_New(tot);

	for (i = 0; tot-- > 0; index++) {
		item = BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, i);
		PyList_SET_ITEM(ret, i++, item);
	}

	return ret;
}