void ItemImpl::copyPersistentReference(CFDataRef &outDataRef, bool isSecIdentityRef)
{
	if (secd_PersistentRef) {
		outDataRef = secd_PersistentRef;
		return;
	}
	StLock<Mutex>_(mMutex);
    // item must be in a keychain and have a primary key to be persistent
    if (!mKeychain || !mPrimaryKey) {
        MacOSError::throwMe(errSecItemNotFound);
    }
    DLDbIdentifier dlDbIdentifier = mKeychain->dlDbIdentifier();
    DLDbIdentifier newDlDbIdentifier(dlDbIdentifier.ssuid(),
        DLDbListCFPref::AbbreviatedPath(mKeychain->name()).c_str(),
        dlDbIdentifier.dbLocation());
    NameValueDictionary dict;
    NameValueDictionary::MakeNameValueDictionaryFromDLDbIdentifier(newDlDbIdentifier, dict);

    CssmData* pKey = mPrimaryKey;
    dict.Insert (new NameValuePair(ITEM_KEY, *pKey));

	if (isSecIdentityRef) {
		uint32_t value = -1;
		CssmData valueData((void*)&value, sizeof(value));
		dict.Insert (new NameValuePair(IDENTITY_KEY, valueData));
	}

    // flatten the NameValueDictionary
    CssmData dictData;
    dict.Export(dictData);
    outDataRef = ::CFDataCreate(kCFAllocatorDefault, dictData.Data, dictData.Length);
    free (dictData.Data);
}
Item ItemImpl::makeFromPersistentReference(const CFDataRef persistentRef, bool *isIdentityRef)
{
	CssmData dictData((void*)::CFDataGetBytePtr(persistentRef), ::CFDataGetLength(persistentRef));
	NameValueDictionary dict(dictData);

	Keychain keychain;
	Item item = (ItemImpl *) NULL;

	if (isIdentityRef) {
		*isIdentityRef = (dict.FindByName(IDENTITY_KEY) != 0) ? true : false;
	}

	// make sure we have a database identifier
	if (dict.FindByName(SSUID_KEY) != 0)
	{
		DLDbIdentifier dlDbIdentifier = NameValueDictionary::MakeDLDbIdentifierFromNameValueDictionary(dict);
		DLDbIdentifier newDlDbIdentifier(dlDbIdentifier.ssuid(),
				DLDbListCFPref::ExpandTildesInPath(dlDbIdentifier.dbName()).c_str(),
				dlDbIdentifier.dbLocation());

		keychain = globals().storageManager.keychain(newDlDbIdentifier);

		const NameValuePair* aDictItem = dict.FindByName(ITEM_KEY);
		if (aDictItem && keychain)
		{
			PrimaryKey primaryKey(aDictItem->Value());
			item = keychain->item(primaryKey);
		}
	}
	KCThrowIf_( !item, errSecItemNotFound );
	return item;
}