XnStatus XnDeviceFileReader::Rewind()
{
	XnStatus nRetVal = XN_STATUS_OK;
	
	// go back to start of stream
	nRetVal = GetIOStream()->Seek(XN_DEVICE_FILE_MAGIC_LEN);
	XN_IS_STATUS_OK(nRetVal);

	// read initial state
	XN_PROPERTY_SET_CREATE_ON_STACK(state);
	nRetVal = ReadInitialState(&state);
	XN_IS_STATUS_OK(nRetVal);

	// first handle current streams. remove or reset them
	XnDeviceModuleHolderList streams;
	nRetVal = GetStreamsList(streams);
	XN_IS_STATUS_OK(nRetVal);

	for (XnDeviceModuleHolderList::Iterator it = streams.Begin(); it != streams.End(); ++it)
	{
		XnDeviceModuleHolder* pHolder = *it;

		if (m_bStreamsCollectionChanged)
		{
			// we need to destroy all streams, and recreate them later
			nRetVal = DestroyStream(pHolder->GetModule()->GetName());
			XN_IS_STATUS_OK(nRetVal);
		}
		else
		{
			// just reset frame ID
			XnStreamReaderStream* pStream = (XnStreamReaderStream*)pHolder->GetModule();
			pStream->Reset();
		}
	}

	// if we need, recreate streams
	if (m_bStreamsCollectionChanged)
	{
		nRetVal = CreateStreams(&state);
		XN_IS_STATUS_OK(nRetVal);
	}

	// now set state.
	for (XnPropertySetData::Iterator it = state.pData->Begin(); it != state.pData->End(); ++it)
	{
		const XnChar* strName = it->Key();
		XnActualPropertiesHash* pHash = it->Value();

		// fix it first
		if (strcmp(strName, XN_MODULE_NAME_DEVICE) == 0)
		{
			pHash->Remove(XN_MODULE_PROPERTY_READ_WRITE_MODE);
			pHash->Remove(XN_MODULE_PROPERTY_PRIMARY_STREAM);
		}

		XnDeviceModule* pModule;
		nRetVal = FindModule(strName, &pModule);
		XN_IS_STATUS_OK(nRetVal);

		nRetVal = pModule->UnsafeBatchConfig(*pHash);
		XN_IS_STATUS_OK(nRetVal);
	}

	ResetLastTimestampAndFrame();
	m_nReferenceTimestamp = 0;
	m_nReferenceTime = 0;
	m_bStreamsCollectionChanged = FALSE;

	return (XN_STATUS_OK);
}