static sdlTypePtr make_persistent_sdl_type(sdlTypePtr type, HashTable *ptr_map, HashTable *bp_types, HashTable *bp_encoders)
{
	zend_string *key;
	sdlTypePtr ptype = NULL;

	ptype = malloc(sizeof(sdlType));
	memset(ptype, 0, sizeof(sdlType));

	*ptype = *type;

	if (ptype->name) {
		ptype->name = strdup(ptype->name);
	}
	if (ptype->namens) {
		ptype->namens = strdup(ptype->namens);
	}
	if (ptype->def) {
		ptype->def = strdup(ptype->def);
	}
	if (ptype->fixed) {
		ptype->fixed = strdup(ptype->fixed);
	}
	if (ptype->ref) {
		ptype->ref = strdup(ptype->ref);
	}

	/* we do not want to process defaultEncoding's here */
	if (ptype->encode) {
		make_persistent_sdl_encoder_ref(&ptype->encode, ptr_map, bp_encoders);
	}

	if (ptype->restrictions) {
		ptype->restrictions = malloc(sizeof(sdlRestrictions));
		memset(ptype->restrictions, 0, sizeof(sdlRestrictions));
		*ptype->restrictions = *type->restrictions;

		if (ptype->restrictions->minExclusive) {
			make_persistent_restriction_int(&ptype->restrictions->minExclusive);
		}
		if (ptype->restrictions->maxExclusive) {
			make_persistent_restriction_int(&ptype->restrictions->maxExclusive);
		}
		if (ptype->restrictions->minInclusive) {
			make_persistent_restriction_int(&ptype->restrictions->minInclusive);
		}
		if (ptype->restrictions->maxInclusive) {
			make_persistent_restriction_int(&ptype->restrictions->maxInclusive);
		}
		if (ptype->restrictions->totalDigits) {
			make_persistent_restriction_int(&ptype->restrictions->totalDigits);
		}
		if (ptype->restrictions->fractionDigits) {
			make_persistent_restriction_int(&ptype->restrictions->fractionDigits);
		}
		if (ptype->restrictions->length) {
			make_persistent_restriction_int(&ptype->restrictions->length);
		}
		if (ptype->restrictions->minLength) {
			make_persistent_restriction_int(&ptype->restrictions->minLength);
		}
		if (ptype->restrictions->maxLength) {
			make_persistent_restriction_int(&ptype->restrictions->maxLength);
		}
		if (ptype->restrictions->whiteSpace) {
			make_persistent_restriction_char_int(&ptype->restrictions->whiteSpace);
		}
		if (ptype->restrictions->pattern) {
			make_persistent_restriction_char_int(&ptype->restrictions->pattern);
		}

		if (type->restrictions->enumeration) {
			sdlRestrictionCharPtr tmp, penum;
			ptype->restrictions->enumeration = malloc(sizeof(HashTable));
			zend_hash_init(ptype->restrictions->enumeration, zend_hash_num_elements(type->restrictions->enumeration), NULL, delete_restriction_var_char_persistent, 1);
			ZEND_HASH_FOREACH_STR_KEY_PTR(type->restrictions->enumeration, key, tmp) {
				penum = tmp;
				make_persistent_restriction_char_int(&penum);
				/* We have to duplicate key emalloc->malloc */
				zend_hash_str_add_ptr(ptype->restrictions->enumeration, ZSTR_VAL(key), ZSTR_LEN(key), penum);
			} ZEND_HASH_FOREACH_END();
		}
	}

	if (ptype->elements) {
		sdlTypePtr tmp, pelem;

		ptype->elements = malloc(sizeof(HashTable));
		zend_hash_init(ptype->elements, zend_hash_num_elements(type->elements), NULL, delete_type_persistent, 1);

		ZEND_HASH_FOREACH_STR_KEY_PTR(type->elements, key, tmp) {
			pelem = make_persistent_sdl_type(tmp, ptr_map, bp_types, bp_encoders);
			if (key) {
				/* We have to duplicate key emalloc->malloc */
				zend_hash_str_add_ptr(ptype->elements, ZSTR_VAL(key), ZSTR_LEN(key), pelem);
			} else {
				zend_hash_next_index_insert_ptr(ptype->elements, pelem);
			}
			zend_hash_str_add_ptr(ptr_map, (char*)&tmp, sizeof(tmp), pelem);
		} ZEND_HASH_FOREACH_END();
	}

	if (ptype->attributes) {
		sdlAttributePtr tmp, pattr;

		ptype->attributes = malloc(sizeof(HashTable));
		zend_hash_init(ptype->attributes, zend_hash_num_elements(type->attributes), NULL, delete_attribute_persistent, 1);

		ZEND_HASH_FOREACH_STR_KEY_PTR(type->attributes, key, tmp) {
			pattr = make_persistent_sdl_attribute(tmp, ptr_map, bp_types, bp_encoders);
			if (key) {
				/* We have to duplicate key emalloc->malloc */
				zend_hash_str_add_ptr(ptype->attributes, ZSTR_VAL(key), ZSTR_LEN(key), pattr);
			} else {
				zend_hash_next_index_insert_ptr(ptype->attributes, pattr);
			}
		} ZEND_HASH_FOREACH_END();
	}

	if (type->model) {
		ptype->model = make_persistent_sdl_model(ptype->model, ptr_map, bp_types, bp_encoders);
	}

	return ptype;
}
static sdlTypePtr make_persistent_sdl_type(sdlTypePtr type, HashTable *ptr_map, HashTable *bp_types, HashTable *bp_encoders)
{
	zend_string *key;
	sdlTypePtr ptype = NULL;

	ptype = malloc(sizeof(sdlType));
	memset(ptype, 0, sizeof(sdlType));

	*ptype = *type;

	if (ptype->name) {
		ptype->name = strdup(ptype->name);
	}
	if (ptype->namens) {
		ptype->namens = strdup(ptype->namens);
	}
	if (ptype->def) {
		ptype->def = strdup(ptype->def);
	}
	if (ptype->fixed) {
		ptype->fixed = strdup(ptype->fixed);
	}
	if (ptype->ref) {
		ptype->ref = strdup(ptype->ref);
	}

	 
	if (ptype->encode) {
		make_persistent_sdl_encoder_ref(&ptype->encode, ptr_map, bp_encoders);
	}

	if (ptype->restrictions) {
		ptype->restrictions = malloc(sizeof(sdlRestrictions));
		memset(ptype->restrictions, 0, sizeof(sdlRestrictions));
		*ptype->restrictions = *type->restrictions;

		if (ptype->restrictions->minExclusive) {
			make_persistent_restriction_int(&ptype->restrictions->minExclusive);
		}
		if (ptype->restrictions->maxExclusive) {
			make_persistent_restriction_int(&ptype->restrictions->maxExclusive);
		}
		if (ptype->restrictions->minInclusive) {
			make_persistent_restriction_int(&ptype->restrictions->minInclusive);
		}
		if (ptype->restrictions->maxInclusive) {
			make_persistent_restriction_int(&ptype->restrictions->maxInclusive);
		}
		if (ptype->restrictions->totalDigits) {
			make_persistent_restriction_int(&ptype->restrictions->totalDigits);
		}
		if (ptype->restrictions->fractionDigits) {
			make_persistent_restriction_int(&ptype->restrictions->fractionDigits);
		}
		if (ptype->restrictions->length) {
			make_persistent_restriction_int(&ptype->restrictions->length);
		}
		if (ptype->restrictions->minLength) {
			make_persistent_restriction_int(&ptype->restrictions->minLength);
		}
		if (ptype->restrictions->maxLength) {
			make_persistent_restriction_int(&ptype->restrictions->maxLength);
		}
		if (ptype->restrictions->whiteSpace) {
			make_persistent_restriction_char_int(&ptype->restrictions->whiteSpace);
		}
		if (ptype->restrictions->pattern) {
			make_persistent_restriction_char_int(&ptype->restrictions->pattern);
		}

		if (type->restrictions->enumeration) {
			sdlRestrictionCharPtr tmp, penum;
			ptype->restrictions->enumeration = malloc(sizeof(HashTable));
			zend_hash_init(ptype->restrictions->enumeration, zend_hash_num_elements(type->restrictions->enumeration), NULL, delete_restriction_var_char_persistent, 1);
			ZEND_HASH_FOREACH_STR_KEY_PTR(type->restrictions->enumeration, key, tmp) {
				penum = tmp;
				make_persistent_restriction_char_int(&penum);
				 
				zend_hash_str_add_ptr(ptype->restrictions->enumeration, ZSTR_VAL(key), ZSTR_LEN(key), penum);
			} ZEND_HASH_FOREACH_END();
		}
	}

	if (ptype->elements) {
		sdlTypePtr tmp, pelem;

		ptype->elements = malloc(sizeof(HashTable));
		zend_hash_init(ptype->elements, zend_hash_num_elements(type->elements), NULL, delete_type_persistent, 1);

		ZEND_HASH_FOREACH_STR_KEY_PTR(type->elements, key, tmp) {
			pelem = make_persistent_sdl_type(tmp, ptr_map, bp_types, bp_encoders);
			if (key) {
				 
				zend_hash_str_add_ptr(ptype->elements, ZSTR_VAL(key), ZSTR_LEN(key), pelem);
			} else {
				zend_hash_next_index_insert_ptr(ptype->elements, pelem);
			}
			zend_hash_str_add_ptr(ptr_map, (char*)&tmp, sizeof(tmp), pelem);
		} ZEND_HASH_FOREACH_END();
	}

	if (ptype->attributes) {
		sdlAttributePtr tmp, pattr;

		ptype->attributes = malloc(sizeof(HashTable));
		zend_hash_init(ptype->attributes, zend_hash_num_elements(type->attributes), NULL, delete_attribute_persistent, 1);

		ZEND_HASH_FOREACH_STR_KEY_PTR(type->attributes, key, tmp) {
			pattr = make_persistent_sdl_attribute(tmp, ptr_map, bp_types, bp_encoders);
			if (key) {
				 
				zend_hash_str_add_ptr(ptype->attributes, ZSTR_VAL(key), ZSTR_LEN(key), pattr);
			} else {
				zend_hash_next_index_insert_ptr(ptype->attributes, pattr);
			}
		} ZEND_HASH_FOREACH_END();
	}

	if (type->model) {
		ptype->model = make_persistent_sdl_model(ptype->model, ptr_map, bp_types, bp_encoders);
	}

	return ptype;
}