Index: src/ch/CustomCopyDlg.cpp
===================================================================
diff -u -rba802caea92ee56a154d1da3fe89a4b2f7875f0e -rb193a95402f2bf4c456fb9d65d111caaf6994823
--- src/ch/CustomCopyDlg.cpp	(.../CustomCopyDlg.cpp)	(revision ba802caea92ee56a154d1da3fe89a4b2f7875f0e)
+++ src/ch/CustomCopyDlg.cpp	(.../CustomCopyDlg.cpp)	(revision b193a95402f2bf4c456fb9d65d111caaf6994823)
@@ -278,11 +278,8 @@
 	lvc.cx=static_cast<int>(0.1*rc.Width());
 	m_ctlFilters.InsertColumn(6, &lvc);
 
-	chcore::TFileFiltersArray afFilters;
-	chcore::GetTaskPropValue<chcore::eTO_Filters>(m_tTaskDefinition.GetConfiguration(), afFilters);
+	m_bFilters = !m_tTaskDefinition.GetFilters().IsEmpty();
 
-	m_bFilters = !afFilters.IsEmpty();
-
 	// other custom flags
 	m_bIgnoreFolders = chcore::GetTaskPropValue<chcore::eTO_IgnoreDirectories>(m_tTaskDefinition.GetConfiguration());
 	m_bForceDirectories = chcore::GetTaskPropValue<chcore::eTO_CreateDirectoriesRelativeToRoot>(m_tTaskDefinition.GetConfiguration());
@@ -379,7 +376,7 @@
 	m_ctlFilters.InsertColumn(6, &lvc);
 
 	// refresh the entries in filters' list
-	chcore::TFileFiltersArray afFilters = chcore::GetTaskPropValue<chcore::eTO_Filters>(m_tTaskDefinition.GetConfiguration());
+	const chcore::TFileFiltersArray& afFilters = m_tTaskDefinition.GetFilters();
 	m_ctlFilters.DeleteAllItems();
 	for(size_t stIndex = 0; stIndex < afFilters.GetSize(); ++stIndex)
 	{
@@ -591,19 +588,18 @@
 void CCustomCopyDlg::OnAddfilterButton() 
 {
 	CFilterDlg dlg;
-	chcore::TString strData;
 
-	chcore::TFileFiltersArray afFilters = chcore::GetTaskPropValue<chcore::eTO_Filters>(m_tTaskDefinition.GetConfiguration());
+	chcore::TFileFiltersArray& afFilters = m_tTaskDefinition.GetFilters();
 	for (size_t i = 0; i < afFilters.GetSize(); i++)
 	{
 		const chcore::TFileFilter* pFilter = afFilters.GetAt(i);
 		BOOST_ASSERT(pFilter);
 		if(pFilter)
 		{
 			if(pFilter->GetUseMask())
-				dlg.m_astrAddMask.Add(pFilter->GetCombinedMask(strData));
+				dlg.m_astrAddMask.Add(pFilter->GetCombinedMask());
 			if(pFilter->GetUseExcludeMask())
-				dlg.m_astrAddExcludeMask.Add(pFilter->GetCombinedExcludeMask(strData));
+				dlg.m_astrAddExcludeMask.Add(pFilter->GetCombinedExcludeMask());
 		}
 	}
 	
@@ -612,7 +608,6 @@
 		if(dlg.m_ffFilter.GetUseMask() || dlg.m_ffFilter.GetUseExcludeMask() || dlg.m_ffFilter.GetUseSize1() || dlg.m_ffFilter.GetUseDateTime1() || dlg.m_ffFilter.GetUseAttributes())
 		{
 			afFilters.Add(dlg.m_ffFilter);
-			chcore::SetTaskPropValue<chcore::eTO_Filters>(m_tTaskDefinition.GetConfiguration(), afFilters);
 			AddFilter(dlg.m_ffFilter);
 		}
 		else
@@ -634,8 +629,7 @@
 	
 	if (rFilter.GetUseMask())
 	{
-		chcore::TString strData;
-		rFilter.GetCombinedMask(strData);
+		chcore::TString strData = rFilter.GetCombinedMask();
 		_tcscpy(szLoaded, strData);
 	}
 	else
@@ -650,8 +644,7 @@
 	
 	if (rFilter.GetUseExcludeMask())
 	{
-		chcore::TString strData;
-		rFilter.GetCombinedExcludeMask(strData);
+		chcore::TString strData = rFilter.GetCombinedExcludeMask();
 		_tcscpy(szLoaded, strData);
 	}
 	else
@@ -760,7 +753,7 @@
 
 void CCustomCopyDlg::OnRemovefilterButton() 
 {
-	chcore::TFileFiltersArray afFilters = chcore::GetTaskPropValue<chcore::eTO_Filters>(m_tTaskDefinition.GetConfiguration());
+	chcore::TFileFiltersArray& afFilters = m_tTaskDefinition.GetFilters();
 
 	POSITION pos;
 	int iItem;
@@ -774,8 +767,6 @@
 			iItem=m_ctlFilters.GetNextSelectedItem(pos);
 			m_ctlFilters.DeleteItem(iItem);
 			afFilters.RemoveAt(iItem);
-
-			chcore::SetTaskPropValue<chcore::eTO_Filters>(m_tTaskDefinition.GetConfiguration(), afFilters);
 		}
 	}
 }
@@ -821,7 +812,7 @@
 	POSITION pos = m_ctlFilters.GetFirstSelectedItemPosition();
 	if(pos != NULL)
 	{
-		chcore::TFileFiltersArray afFilters = chcore::GetTaskPropValue<chcore::eTO_Filters>(m_tTaskDefinition.GetConfiguration());
+		chcore::TFileFiltersArray& afFilters = m_tTaskDefinition.GetFilters();
 
 		int iItem = m_ctlFilters.GetNextSelectedItem(pos);
 		CFilterDlg dlg;
@@ -830,17 +821,16 @@
 		if(pFilter)
 			dlg.m_ffFilter = *pFilter;
 		
-		chcore::TString strData;
 		for(size_t stIndex = 0; stIndex < afFilters.GetSize(); ++stIndex)
 		{
 			pFilter = afFilters.GetAt(stIndex);
 			BOOST_ASSERT(pFilter);
 			if(pFilter)
 			{
 				if(pFilter->GetUseMask() && boost::numeric_cast<int>(stIndex) != iItem)
-					dlg.m_astrAddMask.Add(pFilter->GetCombinedMask(strData));
+					dlg.m_astrAddMask.Add(pFilter->GetCombinedMask());
 				if (pFilter->GetUseExcludeMask() && boost::numeric_cast<int>(stIndex) != iItem)
-					dlg.m_astrAddExcludeMask.Add(pFilter->GetCombinedExcludeMask(strData));
+					dlg.m_astrAddExcludeMask.Add(pFilter->GetCombinedExcludeMask());
 			}
 		}
 
@@ -855,7 +845,6 @@
 				|| dlg.m_ffFilter.GetUseDateTime1() || dlg.m_ffFilter.GetUseAttributes())
 			{
 				afFilters.SetAt(iItem, dlg.m_ffFilter);
-				chcore::SetTaskPropValue<chcore::eTO_Filters>(m_tTaskDefinition.GetConfiguration(), afFilters);
 				AddFilter(dlg.m_ffFilter, iItem);
 			}
 		}
Index: src/ch/FilterDlg.cpp
===================================================================
diff -u -rba802caea92ee56a154d1da3fe89a4b2f7875f0e -rb193a95402f2bf4c456fb9d65d111caaf6994823
--- src/ch/FilterDlg.cpp	(.../FilterDlg.cpp)	(revision ba802caea92ee56a154d1da3fe89a4b2f7875f0e)
+++ src/ch/FilterDlg.cpp	(.../FilterDlg.cpp)	(revision b193a95402f2bf4c456fb9d65d111caaf6994823)
@@ -138,15 +138,14 @@
 	// copy data from TFileFilter to a dialog - mask
 	m_bFilter = m_ffFilter.GetUseMask();
 
-	chcore::TString strData;
-	m_ctlFilter.SetCurSel(m_ctlFilter.AddString(m_ffFilter.GetCombinedMask(strData)));
+	m_ctlFilter.SetCurSel(m_ctlFilter.AddString(m_ffFilter.GetCombinedMask()));
 	for (int i=0;i<m_astrAddMask.GetSize();i++)
 	{
 		m_ctlFilter.AddString(m_astrAddMask.GetAt(i));
 	}
 
 	m_bExclude = m_ffFilter.GetUseExcludeMask();
-	m_ctlExcludeMask.SetCurSel(m_ctlExcludeMask.AddString(m_ffFilter.GetCombinedExcludeMask(strData)));
+	m_ctlExcludeMask.SetCurSel(m_ctlExcludeMask.AddString(m_ffFilter.GetCombinedExcludeMask()));
 	for (int i=0;i<m_astrAddExcludeMask.GetSize();i++)
 		m_ctlExcludeMask.AddString(m_astrAddExcludeMask.GetAt(i));
 
Index: src/libchcore/TDateTime.cpp
===================================================================
diff -u -rb1e03eb232a784d6e2d40f67cbbbb33be0972228 -rb193a95402f2bf4c456fb9d65d111caaf6994823
--- src/libchcore/TDateTime.cpp	(.../TDateTime.cpp)	(revision b1e03eb232a784d6e2d40f67cbbbb33be0972228)
+++ src/libchcore/TDateTime.cpp	(.../TDateTime.cpp)	(revision b193a95402f2bf4c456fb9d65d111caaf6994823)
@@ -228,4 +228,19 @@
 	Serializers::Serialize(rSerializer, m_tTime);
 }
 
+time_t TDateTime::GetAsTimeT() const
+{
+	return m_tTime;
+}
+
+bool TDateTime::operator==(const TDateTime& rSrc) const
+{
+	return m_tTime == rSrc.m_tTime;
+}
+
+bool TDateTime::operator!=(const TDateTime& rSrc) const
+{
+	return m_tTime != rSrc.m_tTime;
+}
+
 END_CHCORE_NAMESPACE
Index: src/libchcore/TDateTime.h
===================================================================
diff -u -rbe30619d750d8663d54cf02e7d4bde2ed2dd8d05 -rb193a95402f2bf4c456fb9d65d111caaf6994823
--- src/libchcore/TDateTime.h	(.../TDateTime.h)	(revision be30619d750d8663d54cf02e7d4bde2ed2dd8d05)
+++ src/libchcore/TDateTime.h	(.../TDateTime.h)	(revision b193a95402f2bf4c456fb9d65d111caaf6994823)
@@ -45,12 +45,16 @@
 	TDateTime& operator=(SYSTEMTIME sysDateTime);
 	TDateTime& operator=(time_t tDateTime);
 
+	bool operator==(const TDateTime& rSrc) const;
+	bool operator!=(const TDateTime& rSrc) const;
+
 	// content modification
 	void Clear();
 	void SetCurrentDateTime();
 
 	// content extraction
 	void GetAsSystemTime(SYSTEMTIME& tSystemTime) const;
+	time_t GetAsTimeT() const;
 	TString Format(bool bUseDate, bool bUseTime) const;
 
 	// comparison
Index: src/libchcore/TFileFilter.cpp
===================================================================
diff -u -ra5aa3c3cb78f3767641de2627d1a49a1dc35b429 -rb193a95402f2bf4c456fb9d65d111caaf6994823
--- src/libchcore/TFileFilter.cpp	(.../TFileFilter.cpp)	(revision a5aa3c3cb78f3767641de2627d1a49a1dc35b429)
+++ src/libchcore/TFileFilter.cpp	(.../TFileFilter.cpp)	(revision b193a95402f2bf4c456fb9d65d111caaf6994823)
@@ -32,55 +32,86 @@
 	return (_tcsicmp(ch1, ch2) == 0);
 }
 
-TFileFilter::TFileFilter()
+TFileFilter::TFileFilter() :
+	m_stObjectID(0),
+	m_setModifications(),
+	m_bUseMask(m_setModifications, false),
+	m_astrMask(m_setModifications),
+	m_bUseExcludeMask(m_setModifications, false),
+	m_astrExcludeMask(m_setModifications),
+	m_bUseSize1(m_setModifications, false),
+	m_eSizeCmpType1(m_setModifications, eSizeCmp_Greater),
+	m_ullSize1(m_setModifications, 0),
+	m_bUseSize2(m_setModifications, false),
+	m_eSizeCmpType2(m_setModifications, eSizeCmp_Less),
+	m_ullSize2(m_setModifications, 0),
+	m_bUseDateTime1(m_setModifications, false),
+	m_eDateType(m_setModifications, eDateType_Created),
+	m_eDateCmpType1(m_setModifications, eDateCmp_Greater),
+	m_bUseDate1(m_setModifications, false),
+	m_bUseTime1(m_setModifications, false),
+	m_tDateTime1(m_setModifications),
+	m_bUseDateTime2(m_setModifications, false),
+	m_eDateCmpType2(m_setModifications, eDateCmp_Less),
+	m_bUseDate2(m_setModifications, false),
+	m_bUseTime2(m_setModifications, false),
+	m_tDateTime2(m_setModifications),
+	m_bUseAttributes(m_setModifications, false),
+	m_iArchive(m_setModifications, 2),
+	m_iReadOnly(m_setModifications, 2),
+	m_iHidden(m_setModifications, 2),
+	m_iSystem(m_setModifications, 2),
+	m_iDirectory(m_setModifications, 2)
 {
-	// files mask
-	m_bUseMask=false;
-	m_astrMask.Clear();
+	m_setModifications[eMod_Added] = true;
 
-	m_bUseExcludeMask=false;
-	m_astrExcludeMask.Clear();
-
-	// size filtering
-	m_bUseSize1=false;
-	m_eSizeCmpType1=eSizeCmp_Greater;
-	m_ullSize1=0;
-	m_bUseSize2=false;
-	m_eSizeCmpType2=eSizeCmp_Less;
-	m_ullSize2=0;
-
-	// date filtering
-	m_bUseDateTime1=false;
-	m_eDateType = eDateType_Created;
-	m_eDateCmpType1 = eDateCmp_Greater;
-	m_bUseDate1 = false;
-	m_bUseTime1 = false;
-	m_tDateTime1.SetCurrentDateTime();
-
-	m_bUseDateTime2=false;
-	m_eDateCmpType2 = eDateCmp_Less;
-	m_bUseDate2=false;
-	m_bUseTime2=false;
-	m_tDateTime2.SetCurrentDateTime();
-
-	// attribute filtering
-	m_bUseAttributes=false;
-	m_iArchive=2;
-	m_iReadOnly=2;
-	m_iHidden=2;
-	m_iSystem=2;
-	m_iDirectory=2;
+	m_tDateTime1.Modify().SetCurrentDateTime();
+	m_tDateTime2.Modify().SetCurrentDateTime();
 }
 
-TFileFilter::TFileFilter(const TFileFilter& rFilter)
+TFileFilter::TFileFilter(const TFileFilter& rFilter) :
+	m_stObjectID(rFilter.m_stObjectID),
+	m_setModifications(rFilter.m_setModifications),
+	m_bUseMask(rFilter.m_bUseMask, m_setModifications),
+	m_astrMask(rFilter.m_astrMask, m_setModifications),
+	m_bUseExcludeMask(rFilter.m_bUseExcludeMask, m_setModifications),
+	m_astrExcludeMask(rFilter.m_astrExcludeMask, m_setModifications),
+	m_bUseSize1(rFilter.m_bUseSize1, m_setModifications),
+	m_eSizeCmpType1(rFilter.m_eSizeCmpType1, m_setModifications),
+	m_ullSize1(rFilter.m_ullSize1, m_setModifications),
+	m_bUseSize2(rFilter.m_bUseSize2, m_setModifications),
+	m_eSizeCmpType2(rFilter.m_eSizeCmpType2, m_setModifications),
+	m_ullSize2(rFilter.m_ullSize2, m_setModifications),
+	m_bUseDateTime1(rFilter.m_bUseDateTime1, m_setModifications),
+	m_eDateType(rFilter.m_eDateType, m_setModifications),
+	m_eDateCmpType1(rFilter.m_eDateCmpType1, m_setModifications),
+	m_bUseDate1(rFilter.m_bUseDate1, m_setModifications),
+	m_bUseTime1(rFilter.m_bUseTime1, m_setModifications),
+	m_tDateTime1(rFilter.m_tDateTime1, m_setModifications),
+	m_bUseDateTime2(rFilter.m_bUseDateTime2, m_setModifications),
+	m_eDateCmpType2(rFilter.m_eDateCmpType2, m_setModifications),
+	m_bUseDate2(rFilter.m_bUseDate2, m_setModifications),
+	m_bUseTime2(rFilter.m_bUseTime2, m_setModifications),
+	m_tDateTime2(rFilter.m_tDateTime2, m_setModifications),
+	m_bUseAttributes(rFilter.m_bUseAttributes, m_setModifications),
+	m_iArchive(rFilter.m_iArchive, m_setModifications),
+	m_iReadOnly(rFilter.m_iReadOnly, m_setModifications),
+	m_iHidden(rFilter.m_iHidden, m_setModifications),
+	m_iSystem(rFilter.m_iSystem, m_setModifications),
+	m_iDirectory(rFilter.m_iDirectory, m_setModifications)
 {
-	*this=rFilter;
 }
 
 TFileFilter& TFileFilter::operator=(const TFileFilter& rFilter)
 {
+	if(this == &rFilter)
+		return *this;
+
+	m_stObjectID = rFilter.m_stObjectID;
+	m_setModifications = rFilter.m_setModifications;
+
 	// files mask
-	m_bUseMask=rFilter.m_bUseMask;
+	m_bUseMask = rFilter.m_bUseMask;
 	m_astrMask = rFilter.m_astrMask;
 
 	m_bUseExcludeMask=rFilter.m_bUseExcludeMask;
@@ -119,16 +150,16 @@
 	return *this;
 }
 
-TString& TFileFilter::GetCombinedMask(TString& strMask) const
+TString TFileFilter::GetCombinedMask() const
 {
-	strMask.Clear();
-	size_t stCount = m_astrMask.GetCount();
+	TString strMask;
+	size_t stCount = m_astrMask.Get().GetCount();
 	if(stCount > 0)
 	{
-		strMask = m_astrMask.GetAt(0);
+		strMask = m_astrMask.Get().GetAt(0);
 		for(size_t stIndex = 1; stIndex < stCount; stIndex++)
 		{
-			strMask += _T("|") + m_astrMask.GetAt(stIndex);
+			strMask += _T("|") + m_astrMask.Get().GetAt(stIndex);
 		}
 	}
 
@@ -137,21 +168,21 @@
 
 void TFileFilter::SetCombinedMask(const TString& pMask)
 {
-	m_astrMask.Clear();
+	m_astrMask.Modify().Clear();
 
-	pMask.Split(_T("|"), m_astrMask);
+	pMask.Split(_T("|"), m_astrMask.Modify());
 }
 
-TString& TFileFilter::GetCombinedExcludeMask(TString& strMask) const
+TString TFileFilter::GetCombinedExcludeMask() const
 {
-	strMask.Clear();
-	size_t stCount = m_astrExcludeMask.GetCount();
+	TString strMask;
+	size_t stCount = m_astrExcludeMask.Get().GetCount();
 	if(stCount > 0)
 	{
-		strMask = m_astrExcludeMask.GetAt(0);
+		strMask = m_astrExcludeMask.Get().GetAt(0);
 		for(size_t stIndex = 1; stIndex < stCount; stIndex++)
 		{
-			strMask += _T("|") + m_astrExcludeMask.GetAt(stIndex);
+			strMask += _T("|") + m_astrExcludeMask.Get().GetAt(stIndex);
 		}
 	}
 
@@ -160,198 +191,122 @@
 
 void TFileFilter::SetCombinedExcludeMask(const TString& pMask)
 {
-	m_astrExcludeMask.Clear();
+	m_astrExcludeMask.Modify().Clear();
 
-	pMask.Split(_T("|"), m_astrExcludeMask);
+	pMask.Split(_T("|"), m_astrExcludeMask.Modify());
 }
 
 void TFileFilter::StoreInConfig(TConfig& rConfig) const
 {
-	SetConfigValue(rConfig, _T("IncludeMask.Use"), m_bUseMask);
-	SetConfigValue(rConfig, _T("IncludeMask.MaskList.Mask"), m_astrMask);
+	SetConfigValue(rConfig, _T("IncludeMask.Use"), m_bUseMask.Get());
+	SetConfigValue(rConfig, _T("IncludeMask.MaskList.Mask"), m_astrMask.Get());
 
-	SetConfigValue(rConfig, _T("ExcludeMask.Use"), m_bUseExcludeMask);
-	SetConfigValue(rConfig, _T("ExcludeMask.MaskList.Mask"), m_astrExcludeMask);
+	SetConfigValue(rConfig, _T("ExcludeMask.Use"), m_bUseExcludeMask.Get());
+	SetConfigValue(rConfig, _T("ExcludeMask.MaskList.Mask"), m_astrExcludeMask.Get());
 
-	SetConfigValue(rConfig, _T("SizeA.Use"), m_bUseSize1);
-	SetConfigValue(rConfig, _T("SizeA.FilteringType"), m_eSizeCmpType1);
-	SetConfigValue(rConfig, _T("SizeA.Value"), m_ullSize1);
-	SetConfigValue(rConfig, _T("SizeB.Use"), m_bUseSize2);
-	SetConfigValue(rConfig, _T("SizeB.FilteringType"), m_eSizeCmpType2);
-	SetConfigValue(rConfig, _T("SizeB.Value"), m_ullSize2);
+	SetConfigValue(rConfig, _T("SizeA.Use"), m_bUseSize1.Get());
+	SetConfigValue(rConfig, _T("SizeA.FilteringType"), m_eSizeCmpType1.Get());
+	SetConfigValue(rConfig, _T("SizeA.Value"), m_ullSize1.Get());
+	SetConfigValue(rConfig, _T("SizeB.Use"), m_bUseSize2.Get());
+	SetConfigValue(rConfig, _T("SizeB.FilteringType"), m_eSizeCmpType2.Get());
+	SetConfigValue(rConfig, _T("SizeB.Value"), m_ullSize2.Get());
 
-	SetConfigValue(rConfig, _T("DateA.Use"), m_bUseDateTime1);
-	SetConfigValue(rConfig, _T("DateA.Type"), m_eDateType);	// created/last modified/last accessed
-	SetConfigValue(rConfig, _T("DateA.FilteringType"), m_eDateCmpType1);	// before/after
-	SetConfigValue(rConfig, _T("DateA.EnableDatePart"), m_bUseDate1);
-	SetConfigValue(rConfig, _T("DateA.EnableTimePart"), m_bUseTime1);
-	SetConfigValue(rConfig, _T("DateA.DateTimeValue"), m_tDateTime1);
+	SetConfigValue(rConfig, _T("DateA.Use"), m_bUseDateTime1.Get());
+	SetConfigValue(rConfig, _T("DateA.Type"), m_eDateType.Get());	// created/last modified/last accessed
+	SetConfigValue(rConfig, _T("DateA.FilteringType"), m_eDateCmpType1.Get());	// before/after
+	SetConfigValue(rConfig, _T("DateA.EnableDatePart"), m_bUseDate1.Get());
+	SetConfigValue(rConfig, _T("DateA.EnableTimePart"), m_bUseTime1.Get());
+	SetConfigValue(rConfig, _T("DateA.DateTimeValue"), m_tDateTime1.Get());
 
-	SetConfigValue(rConfig, _T("DateB.Type"), m_bUseDateTime2);
-	SetConfigValue(rConfig, _T("DateB.FilteringType"), m_eDateCmpType2);
-	SetConfigValue(rConfig, _T("DateB.EnableDatePart"), m_bUseDate2);
-	SetConfigValue(rConfig, _T("DateB.EnableTimePart"), m_bUseTime2);
-	SetConfigValue(rConfig, _T("DateB.DateTimeValue"), m_tDateTime2);
+	SetConfigValue(rConfig, _T("DateB.Type"), m_bUseDateTime2.Get());
+	SetConfigValue(rConfig, _T("DateB.FilteringType"), m_eDateCmpType2.Get());
+	SetConfigValue(rConfig, _T("DateB.EnableDatePart"), m_bUseDate2.Get());
+	SetConfigValue(rConfig, _T("DateB.EnableTimePart"), m_bUseTime2.Get());
+	SetConfigValue(rConfig, _T("DateB.DateTimeValue"), m_tDateTime2.Get());
 
-	SetConfigValue(rConfig, _T("Attributes.Use"), m_bUseAttributes);
-	SetConfigValue(rConfig, _T("Attributes.Archive"), m_iArchive);
-	SetConfigValue(rConfig, _T("Attributes.ReadOnly"), m_iReadOnly);
-	SetConfigValue(rConfig, _T("Attributes.Hidden"), m_iHidden);
-	SetConfigValue(rConfig, _T("Attributes.System"), m_iSystem);
-	SetConfigValue(rConfig, _T("Attributes.Directory"), m_iDirectory);
+	SetConfigValue(rConfig, _T("Attributes.Use"), m_bUseAttributes.Get());
+	SetConfigValue(rConfig, _T("Attributes.Archive"), m_iArchive.Get());
+	SetConfigValue(rConfig, _T("Attributes.ReadOnly"), m_iReadOnly.Get());
+	SetConfigValue(rConfig, _T("Attributes.Hidden"), m_iHidden.Get());
+	SetConfigValue(rConfig, _T("Attributes.System"), m_iSystem.Get());
+	SetConfigValue(rConfig, _T("Attributes.Directory"), m_iDirectory.Get());
 }
 
 void TFileFilter::ReadFromConfig(const TConfig& rConfig)
 {
-	if(!GetConfigValue(rConfig, _T("IncludeMask.Use"), m_bUseMask))
+	if(!GetConfigValue(rConfig, _T("IncludeMask.Use"), m_bUseMask.Modify()))
 		m_bUseMask = false;
 
-	m_astrMask.Clear();
-	GetConfigValue(rConfig, _T("IncludeMask.MaskList.Mask"), m_astrMask);
+	m_astrMask.Modify().Clear();
+	GetConfigValue(rConfig, _T("IncludeMask.MaskList.Mask"), m_astrMask.Modify());
 
-	if(!GetConfigValue(rConfig, _T("ExcludeMask.Use"), m_bUseExcludeMask))
+	if(!GetConfigValue(rConfig, _T("ExcludeMask.Use"), m_bUseExcludeMask.Modify()))
 		m_bUseExcludeMask = false;
 
-	m_astrExcludeMask.Clear();
-	GetConfigValue(rConfig, _T("ExcludeMask.MaskList.Mask"), m_astrExcludeMask);
+	m_astrExcludeMask.Modify().Clear();
+	GetConfigValue(rConfig, _T("ExcludeMask.MaskList.Mask"), m_astrExcludeMask.Modify());
 
-	if(!GetConfigValue(rConfig, _T("SizeA.Use"), m_bUseSize1))
+	if(!GetConfigValue(rConfig, _T("SizeA.Use"), m_bUseSize1.Modify()))
 		m_bUseSize1 = false;
-	if(!GetConfigValue(rConfig, _T("SizeA.FilteringType"), *(int*)m_eSizeCmpType1))
+	if(!GetConfigValue(rConfig, _T("SizeA.FilteringType"), *(int*)m_eSizeCmpType1.Modify()))
 		m_eSizeCmpType1 = eSizeCmp_Equal;
-	if(!GetConfigValue(rConfig, _T("SizeA.Value"), m_ullSize1))
+	if(!GetConfigValue(rConfig, _T("SizeA.Value"), m_ullSize1.Modify()))
 		m_ullSize1 = 0;
-	if(!GetConfigValue(rConfig, _T("SizeB.Use"), m_bUseSize2))
+	if(!GetConfigValue(rConfig, _T("SizeB.Use"), m_bUseSize2.Modify()))
 		m_bUseSize2 = false;
-	if(!GetConfigValue(rConfig, _T("SizeB.FilteringType"), *(int*)m_eSizeCmpType2))
+	if(!GetConfigValue(rConfig, _T("SizeB.FilteringType"), *(int*)m_eSizeCmpType2.Modify()))
 		m_eSizeCmpType2 = eSizeCmp_Equal;
-	if(!GetConfigValue(rConfig, _T("SizeB.Value"), m_ullSize2))
+	if(!GetConfigValue(rConfig, _T("SizeB.Value"), m_ullSize2.Modify()))
 		m_ullSize2 = 0;
 
-	if(!GetConfigValue(rConfig, _T("DateA.Use"), m_bUseDateTime1))
+	if(!GetConfigValue(rConfig, _T("DateA.Use"), m_bUseDateTime1.Modify()))
 		m_bUseDateTime1 = false;
 
-	if(!GetConfigValue(rConfig, _T("DateA.Type"), *(int*)m_eDateType))	// created/last modified/last accessed
+	if(!GetConfigValue(rConfig, _T("DateA.Type"), *(int*)m_eDateType.Modify()))	// created/last modified/last accessed
 		m_eDateType = eDateType_Created;
-	if(!GetConfigValue(rConfig, _T("DateA.FilteringType"), *(int*)m_eDateCmpType1))	// before/after
+	if(!GetConfigValue(rConfig, _T("DateA.FilteringType"), *(int*)m_eDateCmpType1.Modify()))	// before/after
 		m_eDateCmpType1 = eDateCmp_Equal;
-	if(!GetConfigValue(rConfig, _T("DateA.EnableDatePart"), m_bUseDate1))
+	if(!GetConfigValue(rConfig, _T("DateA.EnableDatePart"), m_bUseDate1.Modify()))
 		m_bUseDate1 = false;
-	if(!GetConfigValue(rConfig, _T("DateA.EnableTimePart"), m_bUseTime1))
+	if(!GetConfigValue(rConfig, _T("DateA.EnableTimePart"), m_bUseTime1.Modify()))
 		m_bUseTime1 = false;
 
-	if(!GetConfigValue(rConfig, _T("DateA.DateTimeValue"), m_tDateTime1))
-		m_tDateTime1.Clear();
+	if(!GetConfigValue(rConfig, _T("DateA.DateTimeValue"), m_tDateTime1.Modify()))
+		m_tDateTime1.Modify().Clear();
 
-	if(!GetConfigValue(rConfig, _T("DateB.Type"), m_bUseDateTime2))
+	if(!GetConfigValue(rConfig, _T("DateB.Type"), m_bUseDateTime2.Modify()))
 		m_bUseDateTime2 = false;
-	if(!GetConfigValue(rConfig, _T("DateB.FilteringType"), *(int*)m_eDateCmpType2))
+	if(!GetConfigValue(rConfig, _T("DateB.FilteringType"), *(int*)m_eDateCmpType2.Modify()))
 		m_eDateCmpType2 = eDateCmp_Equal;
-	if(!GetConfigValue(rConfig, _T("DateB.EnableDatePart"), m_bUseDate2))
+	if(!GetConfigValue(rConfig, _T("DateB.EnableDatePart"), m_bUseDate2.Modify()))
 		m_bUseDate2 = false;
 
-	if(!GetConfigValue(rConfig, _T("DateB.DateTimeValue"), m_tDateTime2))
-		m_tDateTime2.Clear();
-	if(!GetConfigValue(rConfig, _T("DateB.EnableTimePart"), m_bUseTime2))
+	if(!GetConfigValue(rConfig, _T("DateB.DateTimeValue"), m_tDateTime2.Modify()))
+		m_tDateTime2.Modify().Clear();
+	if(!GetConfigValue(rConfig, _T("DateB.EnableTimePart"), m_bUseTime2.Modify()))
 		m_bUseTime2 = false;
 
-	if(!GetConfigValue(rConfig, _T("Attributes.Use"), m_bUseAttributes))
+	if(!GetConfigValue(rConfig, _T("Attributes.Use"), m_bUseAttributes.Modify()))
 		m_bUseAttributes = false;
-	if(!GetConfigValue(rConfig, _T("Attributes.Archive"), m_iArchive))
+	if(!GetConfigValue(rConfig, _T("Attributes.Archive"), m_iArchive.Modify()))
 		m_iArchive = 0;
-	if(!GetConfigValue(rConfig, _T("Attributes.ReadOnly"), m_iReadOnly))
+	if(!GetConfigValue(rConfig, _T("Attributes.ReadOnly"), m_iReadOnly.Modify()))
 		m_iReadOnly = false;
-	if(!GetConfigValue(rConfig, _T("Attributes.Hidden"), m_iHidden))
+	if(!GetConfigValue(rConfig, _T("Attributes.Hidden"), m_iHidden.Modify()))
 		m_iHidden = 0;
-	if(!GetConfigValue(rConfig, _T("Attributes.System"), m_iSystem))
+	if(!GetConfigValue(rConfig, _T("Attributes.System"), m_iSystem.Modify()))
 		m_iSystem = 0;
-	if(!GetConfigValue(rConfig, _T("Attributes.Directory"), m_iDirectory))
+	if(!GetConfigValue(rConfig, _T("Attributes.Directory"), m_iDirectory.Modify()))
 		m_iDirectory = 0;
 }
 
-void TFileFilter::Serialize(TReadBinarySerializer& rSerializer)
-{
-	using Serializers::Serialize;
-
-	Serialize(rSerializer, m_bUseMask);
-	Serialize(rSerializer, m_astrMask);
-
-	Serialize(rSerializer, m_bUseExcludeMask);
-	Serialize(rSerializer, m_astrExcludeMask);
-
-	Serialize(rSerializer, m_bUseSize1);
-	Serialize(rSerializer, m_eSizeCmpType1);
-	Serialize(rSerializer, m_ullSize1);
-	Serialize(rSerializer, m_bUseSize2);
-	Serialize(rSerializer, m_eSizeCmpType2);
-	Serialize(rSerializer, m_ullSize2);
-
-	Serialize(rSerializer, m_bUseDateTime1);
-	Serialize(rSerializer, m_eDateType);	// created/last modified/last accessed
-	Serialize(rSerializer, m_eDateCmpType1);	// before/after
-	Serialize(rSerializer, m_bUseDate1);
-	Serialize(rSerializer, m_bUseTime1);
-	Serialize(rSerializer, m_tDateTime1);
-
-	Serialize(rSerializer, m_bUseDateTime2);
-	Serialize(rSerializer, m_eDateCmpType2);
-	Serialize(rSerializer, m_bUseDate2);
-	Serialize(rSerializer, m_bUseTime2);
-	Serialize(rSerializer, m_tDateTime2);
-
-	Serialize(rSerializer, m_bUseAttributes);
-	Serialize(rSerializer, m_iArchive);
-	Serialize(rSerializer, m_iReadOnly);
-	Serialize(rSerializer, m_iHidden);
-	Serialize(rSerializer, m_iSystem);
-	Serialize(rSerializer, m_iDirectory);
-}
-
-void TFileFilter::Serialize(TWriteBinarySerializer& rSerializer) const
-{
-	using Serializers::Serialize;
-
-	Serialize(rSerializer, m_bUseMask);
-	Serialize(rSerializer, m_astrMask);
-
-	Serialize(rSerializer, m_bUseExcludeMask);
-	Serialize(rSerializer, m_astrExcludeMask);
-
-	Serialize(rSerializer, m_bUseSize1);
-	Serialize(rSerializer, m_eSizeCmpType1);
-	Serialize(rSerializer, m_ullSize1);
-	Serialize(rSerializer, m_bUseSize2);
-	Serialize(rSerializer, m_eSizeCmpType2);
-	Serialize(rSerializer, m_ullSize2);
-
-	Serialize(rSerializer, m_bUseDateTime1);
-	Serialize(rSerializer, m_eDateType);	// created/last modified/last accessed
-	Serialize(rSerializer, m_eDateCmpType1);	// before/after
-	Serialize(rSerializer, m_bUseDate1);
-	Serialize(rSerializer, m_bUseTime1);
-	Serialize(rSerializer, m_tDateTime1);
-
-	Serialize(rSerializer, m_bUseDateTime2);
-	Serialize(rSerializer, m_eDateCmpType2);
-	Serialize(rSerializer, m_bUseDate2);
-	Serialize(rSerializer, m_bUseTime2);
-	Serialize(rSerializer, m_tDateTime2);
-
-	Serialize(rSerializer, m_bUseAttributes);
-	Serialize(rSerializer, m_iArchive);
-	Serialize(rSerializer, m_iReadOnly);
-	Serialize(rSerializer, m_iHidden);
-	Serialize(rSerializer, m_iSystem);
-	Serialize(rSerializer, m_iDirectory);
-}
-
 bool TFileFilter::Match(const TFileInfoPtr& spInfo) const
 {
 	// check by mask
 	if(m_bUseMask)
 	{
 		bool bRes=false;
-		for(TStringArray::const_iterator iterMask = m_astrMask.Begin(); iterMask != m_astrMask.End(); ++iterMask)
+		for(TStringArray::const_iterator iterMask = m_astrMask.Get().Begin(); iterMask != m_astrMask.Get().End(); ++iterMask)
 		{
 			if(MatchMask(*iterMask, spInfo->GetFullFilePath().GetFileName().ToString()))
 				bRes = true;
@@ -363,7 +318,7 @@
 	// excluding mask
 	if(m_bUseExcludeMask)
 	{
-		for(TStringArray::const_iterator iterExcludeMask = m_astrExcludeMask.Begin(); iterExcludeMask != m_astrExcludeMask.End(); ++iterExcludeMask)
+		for(TStringArray::const_iterator iterExcludeMask = m_astrExcludeMask.Get().Begin(); iterExcludeMask != m_astrExcludeMask.Get().End(); ++iterExcludeMask)
 		{
 			if(MatchMask(*iterExcludeMask, spInfo->GetFullFilePath().GetFileName().ToString()))
 				return false;
@@ -444,7 +399,7 @@
 		}
 
 		// counting...
-		time_t tDiff = m_tDateTime1.Compare(tDateTime, m_bUseDate1, m_bUseTime1);
+		time_t tDiff = m_tDateTime1.Get().Compare(tDateTime, m_bUseDate1, m_bUseTime1);
 
 		// ... and comparing
 		switch(m_eDateCmpType1)
@@ -474,7 +429,7 @@
 		if (m_bUseDateTime2)
 		{
 			// counting...
-			tDiff = m_tDateTime2.Compare(tDateTime, m_bUseDate2, m_bUseTime2);
+			tDiff = m_tDateTime2.Get().Compare(tDateTime, m_bUseDate2, m_bUseTime2);
 
 			// ... comparing
 			switch (m_eDateCmpType2)
@@ -581,4 +536,435 @@
 	}
 }
 
+void TFileFilter::SetupLoader(const IColumnsDefinitionPtr& spColumns)
+{
+	*spColumns
+		% _T("id")
+		% _T("use_mask")
+		% _T("mask")
+		% _T("use_exclude_mask")
+		% _T("exclude_mask")
+		% _T("use_size_1")
+		% _T("compare_type_1")
+		% _T("size_1")
+		% _T("use_size_2")
+		% _T("compare_type_2")
+		% _T("size_2")
+		% _T("date_type")
+		% _T("use_date_time_1")
+		% _T("date_compare_type_1")
+		% _T("use_date_1")
+		% _T("use_time_1")
+		% _T("datetime_1")
+		% _T("use_date_time_2")
+		% _T("date_compare_type_2")
+		% _T("use_date_2")
+		% _T("use_time_2")
+		% _T("datetime_2")
+		% _T("use_attributes")
+		% _T("attr_archive")
+		% _T("attr_ro")
+		% _T("attr_hidden")
+		% _T("attr_system")
+		% _T("attr_directory");
+}
+
+void TFileFilter::Store(const ISerializerContainerPtr& spContainer) const
+{
+	ISerializerRowDataPtr spRow;
+
+	bool bAdded = m_setModifications[eMod_Added];
+	if(bAdded)
+		spRow = spContainer->AddRow(m_stObjectID);
+	else if(m_setModifications.any())
+		spRow = spContainer->GetRow(m_stObjectID);
+	else
+		return;
+
+	if(bAdded || m_setModifications[eMod_UseMask])
+		*spRow % TRowData(_T("use_mask"), m_bUseMask);
+	if(bAdded || m_setModifications[eMod_Mask])
+		*spRow % TRowData(_T("mask"), GetCombinedMask());
+	if(bAdded || m_setModifications[eMod_UseExcludeMask])
+		*spRow % TRowData(_T("use_exclude_mask"), m_bUseExcludeMask);
+	if(bAdded || m_setModifications[eMod_ExcludeMask])
+		*spRow % TRowData(_T("exclude_mask"), GetCombinedExcludeMask());
+	if(bAdded || m_setModifications[eMod_UseSize1])
+		*spRow % TRowData(_T("use_size_1"), m_bUseSize1);
+	if(bAdded || m_setModifications[eMod_SizeCmpType1])
+		*spRow % TRowData(_T("compare_type_1"), m_eSizeCmpType1);
+	if(bAdded || m_setModifications[eMod_Size1])
+		*spRow % TRowData(_T("size_1"), m_ullSize1);
+	if(bAdded || m_setModifications[eMod_UseSize2])
+		*spRow % TRowData(_T("use_size_2"), m_bUseSize2);
+	if(bAdded || m_setModifications[eMod_SizeCmpType2])
+		*spRow % TRowData(_T("compare_type_2"), m_eSizeCmpType2);
+	if(bAdded || m_setModifications[eMod_Size2])
+		*spRow % TRowData(_T("size_2"), m_ullSize2);
+	if(bAdded || m_setModifications[eMod_DateType])
+		*spRow % TRowData(_T("date_type"), m_eDateType);
+	if(bAdded || m_setModifications[eMod_UseDateTime1])
+		*spRow % TRowData(_T("use_date_time_1"), m_bUseDateTime1);
+	if(bAdded || m_setModifications[eMod_DateCmpType1])
+		*spRow % TRowData(_T("date_compare_type_1"), m_eDateCmpType1);
+	if(bAdded || m_setModifications[eMod_UseDate1])
+		*spRow % TRowData(_T("use_date_1"), m_bUseDate1);
+	if(bAdded || m_setModifications[eMod_UseTime1])
+		*spRow % TRowData(_T("use_time_1"), m_bUseTime1);
+	if(bAdded || m_setModifications[eMod_DateTime1])
+		*spRow % TRowData(_T("datetime_1"), m_tDateTime1.Get().GetAsTimeT());
+	if(bAdded || m_setModifications[eMod_UseDateTime2])
+		*spRow % TRowData(_T("use_date_time_2"), m_bUseDateTime2);
+	if(bAdded || m_setModifications[eMod_DateCmpType2])
+		*spRow % TRowData(_T("date_compare_type_2"), m_eDateCmpType2);
+	if(bAdded || m_setModifications[eMod_UseDate2])
+		*spRow % TRowData(_T("use_date_2"), m_bUseDate2);
+	if(bAdded || m_setModifications[eMod_UseTime2])
+		*spRow % TRowData(_T("use_time_2"), m_bUseTime2);
+	if(bAdded || m_setModifications[eMod_DateTime2])
+		*spRow % TRowData(_T("datetime_2"), m_tDateTime2.Get().GetAsTimeT());
+	if(bAdded || m_setModifications[eMod_UseAttributes])
+		*spRow % TRowData(_T("use_attributes"), m_bUseAttributes);
+	if(bAdded || m_setModifications[eMod_AttrArchive])
+		*spRow % TRowData(_T("attr_archive"), m_iArchive);
+	if(bAdded || m_setModifications[eMod_AttrReadOnly])
+		*spRow % TRowData(_T("attr_ro"), m_iReadOnly);
+	if(bAdded || m_setModifications[eMod_AttrHidden])
+		*spRow % TRowData(_T("attr_hidden"), m_iHidden);
+	if(bAdded || m_setModifications[eMod_AttrSystem])
+		*spRow % TRowData(_T("attr_system"), m_iSystem);
+	if(bAdded || m_setModifications[eMod_AttrDirectory])
+		*spRow % TRowData(_T("attr_directory"), m_iDirectory);
+
+	m_setModifications.reset();
+}
+
+void TFileFilter::Load(const ISerializerRowReaderPtr& spRowReader)
+{
+	time_t tValue = 0;
+	TString strMask;
+
+	spRowReader->GetValue(_T("use_mask"), m_bUseMask.Modify());
+	spRowReader->GetValue(_T("mask"), strMask);
+	SetCombinedMask(strMask);
+	spRowReader->GetValue(_T("use_exclude_mask"), m_bUseExcludeMask.Modify());
+	spRowReader->GetValue(_T("exclude_mask"), strMask);
+	SetCombinedExcludeMask(strMask);
+	spRowReader->GetValue(_T("use_size_1"), m_bUseSize1.Modify());
+	spRowReader->GetValue(_T("compare_type_1"), *(int*)&m_eSizeCmpType1.Modify());
+	spRowReader->GetValue(_T("size_1"), m_ullSize1.Modify());
+	spRowReader->GetValue(_T("use_size_2"), m_bUseSize2.Modify());
+	spRowReader->GetValue(_T("compare_type_2"), *(int*)&m_eSizeCmpType2.Modify());
+	spRowReader->GetValue(_T("size_2"), m_ullSize2.Modify());
+	spRowReader->GetValue(_T("date_type"), *(int*)&m_eDateType.Modify());
+	spRowReader->GetValue(_T("use_date_time_1"), m_bUseDateTime1.Modify());
+	spRowReader->GetValue(_T("date_compare_type_1"), *(int*)&m_eDateCmpType1.Modify());
+	spRowReader->GetValue(_T("use_date_1"), m_bUseDate1.Modify());
+	spRowReader->GetValue(_T("use_time_1"), m_bUseTime1.Modify());
+	spRowReader->GetValue(_T("datetime_1"), tValue);
+	m_tDateTime1 = tValue;
+	spRowReader->GetValue(_T("use_date_time_2"), m_bUseDateTime2.Modify());
+	spRowReader->GetValue(_T("date_compare_type_2"), *(int*)&m_eDateCmpType2.Modify());
+	spRowReader->GetValue(_T("use_date_2"), m_bUseDate2.Modify());
+	spRowReader->GetValue(_T("use_time_2"), m_bUseTime2.Modify());
+	spRowReader->GetValue(_T("datetime_2"), tValue);
+	m_tDateTime2 = tValue;
+	spRowReader->GetValue(_T("use_attributes"), m_bUseAttributes.Modify());
+	spRowReader->GetValue(_T("attr_archive"), m_iArchive.Modify());
+	spRowReader->GetValue(_T("attr_ro"), m_iReadOnly.Modify());
+	spRowReader->GetValue(_T("attr_hidden"), m_iHidden.Modify());
+	spRowReader->GetValue(_T("attr_system"), m_iSystem.Modify());
+	spRowReader->GetValue(_T("attr_directory"), m_iDirectory.Modify());
+
+	m_setModifications.reset();
+}
+
+size_t TFileFilter::GetObjectID() const
+{
+	return m_stObjectID;
+}
+
+void TFileFilter::SetObjectID(size_t stObjectID)
+{
+	m_stObjectID = stObjectID;
+}
+
+void TFileFilter::ResetModifications()
+{
+	m_setModifications.reset();
+}
+
+void TFileFilter::SetData(const TFileFilter& rFilter)
+{
+	if(this == &rFilter)
+		return;
+
+	// files mask
+	m_bUseMask = rFilter.m_bUseMask;
+	m_astrMask = rFilter.m_astrMask;
+
+	m_bUseExcludeMask = rFilter.m_bUseExcludeMask;
+	m_astrExcludeMask = rFilter.m_astrExcludeMask;
+
+	// size filtering
+	m_bUseSize1 = rFilter.m_bUseSize1;
+	m_eSizeCmpType1 = rFilter.m_eSizeCmpType1;
+	m_ullSize1 = rFilter.m_ullSize1;
+	m_bUseSize2 = rFilter.m_bUseSize2;
+	m_eSizeCmpType2 = rFilter.m_eSizeCmpType2;
+	m_ullSize2 = rFilter.m_ullSize2;
+
+	// date filtering
+	m_bUseDateTime1 = rFilter.m_bUseDateTime1;
+	m_eDateType = rFilter.m_eDateType;
+	m_eDateCmpType1 = rFilter.m_eDateCmpType1;
+	m_bUseDate1 = rFilter.m_bUseDate1;
+	m_bUseTime1 = rFilter.m_bUseTime1;
+	m_tDateTime1 = rFilter.m_tDateTime1;
+
+	m_bUseDateTime2 = rFilter.m_bUseDateTime2;
+	m_eDateCmpType2 = rFilter.m_eDateCmpType2;
+	m_bUseDate2 = rFilter.m_bUseDate2;
+	m_bUseTime2 = rFilter.m_bUseTime2;
+	m_tDateTime2 = rFilter.m_tDateTime2;
+
+	// attribute filtering
+	m_bUseAttributes = rFilter.m_bUseAttributes;
+	m_iArchive = rFilter.m_iArchive;
+	m_iReadOnly = rFilter.m_iReadOnly;
+	m_iHidden = rFilter.m_iHidden;
+	m_iSystem = rFilter.m_iSystem;
+	m_iDirectory = rFilter.m_iDirectory;
+}
+
+void TFileFilter::SetUseMask(bool bUseMask)
+{
+	m_bUseMask = bUseMask;
+}
+
+bool TFileFilter::GetUseMask() const
+{
+	return m_bUseMask;
+}
+
+bool TFileFilter::GetUseExcludeMask() const
+{
+	return m_bUseExcludeMask;
+}
+
+void TFileFilter::SetUseExcludeMask(bool bUseExcludeMask)
+{
+	m_bUseExcludeMask = bUseExcludeMask;
+}
+
+bool TFileFilter::GetUseSize1() const
+{
+	return m_bUseSize1;
+}
+
+void TFileFilter::SetUseSize1(bool bUseSize1)
+{
+	m_bUseSize1 = bUseSize1;
+}
+
+chcore::TFileFilter::ESizeCompareType TFileFilter::GetSizeType1() const
+{
+	return m_eSizeCmpType1;
+}
+
+void TFileFilter::SetSizeType1(ESizeCompareType eSizeType1)
+{
+	m_eSizeCmpType1 = eSizeType1;
+}
+
+unsigned long long TFileFilter::GetSize1() const
+{
+	return m_ullSize1;
+}
+
+void TFileFilter::SetSize1(unsigned long long ullSize1)
+{
+	m_ullSize1 = ullSize1;
+}
+
+bool TFileFilter::GetUseSize2() const
+{
+	return m_bUseSize2;
+}
+
+void TFileFilter::SetUseSize2(bool bUseSize2)
+{
+	m_bUseSize2 = bUseSize2;
+}
+
+chcore::TFileFilter::ESizeCompareType TFileFilter::GetSizeType2() const
+{
+	return m_eSizeCmpType2;
+}
+
+void TFileFilter::SetSizeType2(ESizeCompareType eSizeType2)
+{
+	m_eSizeCmpType2 = eSizeType2;
+}
+
+unsigned long long TFileFilter::GetSize2() const
+{
+	return m_ullSize2;
+}
+
+void TFileFilter::SetSize2(unsigned long long ullSize2)
+{
+	m_ullSize2 = ullSize2;
+}
+
+TFileFilter::EDateType TFileFilter::GetDateType() const
+{
+	return m_eDateType;
+}
+
+void TFileFilter::SetDateType(TFileFilter::EDateType eDateType)
+{
+	m_eDateType = eDateType;
+}
+
+bool TFileFilter::GetUseDateTime1() const
+{
+	return m_bUseDateTime1;
+}
+
+void TFileFilter::SetUseDateTime1(bool bUseDateTime1)
+{
+	m_bUseDateTime1 = bUseDateTime1;
+}
+
+TFileFilter::EDateCompareType TFileFilter::GetDateCmpType1() const
+{
+	return m_eDateCmpType1;
+}
+
+void TFileFilter::SetDateCmpType1(TFileFilter::EDateCompareType eCmpType1)
+{
+	m_eDateCmpType1 = eCmpType1;
+}
+
+bool TFileFilter::GetUseDate1() const
+{
+	return m_bUseDate1;
+}
+
+void TFileFilter::SetUseDate1(bool tDate1)
+{
+	m_bUseDate1 = tDate1;
+}
+
+bool TFileFilter::GetUseTime1() const
+{
+	return m_bUseTime1;
+}
+
+void TFileFilter::SetUseTime1(bool tTime1)
+{
+	m_bUseTime1 = tTime1;
+}
+
+const TDateTime& TFileFilter::GetDateTime1() const
+{
+	return m_tDateTime1;
+}
+
+void TFileFilter::SetDateTime1(const TDateTime& tDateTime1)
+{
+	m_tDateTime1 = tDateTime1;
+}
+
+bool TFileFilter::GetUseDateTime2() const
+{
+	return m_bUseDateTime2;
+}
+
+void TFileFilter::SetUseDateTime2(bool bUseDateTime2)
+{
+	m_bUseDateTime2 = bUseDateTime2;
+}
+
+TFileFilter::EDateCompareType TFileFilter::GetDateCmpType2() const
+{
+	return m_eDateCmpType2;
+}
+
+void TFileFilter::SetDateCmpType2(TFileFilter::EDateCompareType eCmpType2)
+{
+	m_eDateCmpType2 = eCmpType2;
+}
+
+bool TFileFilter::GetUseDate2() const
+{
+	return m_bUseDate2;
+}
+
+void TFileFilter::SetUseDate2(bool tDate2)
+{
+	m_bUseDate2 = tDate2;
+}
+
+bool TFileFilter::GetUseTime2() const
+{
+	return m_bUseTime2;
+}
+
+void TFileFilter::SetUseTime2(bool tTime2)
+{
+	m_bUseTime2 = tTime2;
+}
+
+const TDateTime& TFileFilter::GetDateTime2() const
+{
+	return m_tDateTime2;
+}
+
+void TFileFilter::SetDateTime2(const TDateTime& tDateTime2)
+{
+	m_tDateTime2 = tDateTime2;
+}
+
+bool TFileFilter::GetUseAttributes() const
+{
+	return m_bUseAttributes;
+}
+
+void TFileFilter::SetUseAttributes(bool bUseAttributes)
+{
+	m_bUseAttributes = bUseAttributes;
+}
+
+int TFileFilter::GetArchive() const
+{
+	return m_iArchive;
+}
+
+void TFileFilter::SetArchive(int iArchive)
+{
+	m_iArchive = iArchive;
+}
+
+int TFileFilter::GetReadOnly() const
+{
+	return m_iReadOnly;
+}
+
+void TFileFilter::SetReadOnly(int iReadOnly)
+{
+	m_iReadOnly = iReadOnly;
+}
+
+int TFileFilter::GetHidden() const
+{
+	return m_iHidden;
+}
+
+void TFileFilter::SetHidden(int iHidden)
+{
+	m_iHidden = iHidden;
+}
+
 END_CHCORE_NAMESPACE
Index: src/libchcore/TFileFilter.h
===================================================================
diff -u -rb1e03eb232a784d6e2d40f67cbbbb33be0972228 -rb193a95402f2bf4c456fb9d65d111caaf6994823
--- src/libchcore/TFileFilter.h	(.../TFileFilter.h)	(revision b1e03eb232a784d6e2d40f67cbbbb33be0972228)
+++ src/libchcore/TFileFilter.h	(.../TFileFilter.h)	(revision b193a95402f2bf4c456fb9d65d111caaf6994823)
@@ -23,6 +23,8 @@
 #include <atltime.h>
 #include "TDateTime.h"
 #include "TStringArray.h"
+#include <bitset>
+#include "TSharedModificationTracker.h"
 
 BEGIN_CHCORE_NAMESPACE
 
@@ -63,99 +65,112 @@
 	TFileFilter(const TFileFilter& rFilter);
 	TFileFilter& operator=(const TFileFilter& rFilter);
 
+	void SetData(const TFileFilter& rSrc);
+
+	// matching
 	bool Match(const TFileInfoPtr& spInfo) const;
 
-	TString& GetCombinedMask(TString& pMask) const;
-	void SetCombinedMask(const TString& pMask);
-
-	TString& GetCombinedExcludeMask(TString& pMask) const;
-	void SetCombinedExcludeMask(const TString& pMask);
-
+	// serialization
 	void StoreInConfig(TConfig& rConfig) const;
 	void ReadFromConfig(const TConfig& rConfig);
 
 	void Serialize(TReadBinarySerializer& rSerializer);
 	void Serialize(TWriteBinarySerializer& rSerializer) const;
 
+	void Store(const ISerializerContainerPtr& spContainer) const;
+	void Load(const ISerializerRowReaderPtr& spRowReader);
+	static void SetupLoader(const IColumnsDefinitionPtr& spColumns);
+
+	// other
+	size_t GetObjectID() const;
+	void SetObjectID(size_t stObjectID);
+	void ResetModifications();
+
 	// atrributes access
-	bool GetUseMask() const { return m_bUseMask; }
-	void SetUseMask(bool bUseMask) { m_bUseMask = bUseMask; }
+	bool GetUseMask() const;
+	void SetUseMask(bool bUseMask);
 
+	TString GetCombinedMask() const;
+	void SetCombinedMask(const TString& pMask);
+
 	//   const TStringArray& GetMaskArray() const { return m_astrMask; }
 	//   TStringArray& GetMaskArray() { return m_astrMask; }
 
-	bool GetUseExcludeMask() const { return m_bUseExcludeMask; }
-	void SetUseExcludeMask(bool bUseExcludeMask) { m_bUseExcludeMask = bUseExcludeMask; }
+	bool GetUseExcludeMask() const;
+	void SetUseExcludeMask(bool bUseExcludeMask);
 
+	TString GetCombinedExcludeMask() const;
+	void SetCombinedExcludeMask(const TString& pMask);
+
 	//   const TStringArray& GetExcludeMaskArray() const { return m_astrExcludeMask; }
 	//   TStringArray& GetExcludeMaskArray() { return m_astrExcludeMask; }
 
-	bool GetUseSize1() const { return m_bUseSize1; }
-	void SetUseSize1(bool bUseSize1) { m_bUseSize1 = bUseSize1; }
+	bool GetUseSize1() const;
+	void SetUseSize1(bool bUseSize1);
 
-	ESizeCompareType GetSizeType1() const { return m_eSizeCmpType1; }
-	void SetSizeType1(ESizeCompareType eSizeType1) { m_eSizeCmpType1 = eSizeType1; }
+	ESizeCompareType GetSizeType1() const;
+	void SetSizeType1(ESizeCompareType eSizeType1);
 
-	unsigned long long GetSize1() const { return m_ullSize1; }
-	void SetSize1(unsigned long long ullSize1) { m_ullSize1 = ullSize1; }
+	unsigned long long GetSize1() const;
+	void SetSize1(unsigned long long ullSize1);
 
-	bool GetUseSize2() const { return m_bUseSize2; }
-	void SetUseSize2(bool bUseSize2) { m_bUseSize2 = bUseSize2; }
+	bool GetUseSize2() const;
+	void SetUseSize2(bool bUseSize2);
 
-	ESizeCompareType GetSizeType2() const { return m_eSizeCmpType2; }
-	void SetSizeType2(ESizeCompareType eSizeType2) { m_eSizeCmpType2 = eSizeType2; }
+	ESizeCompareType GetSizeType2() const;
+	void SetSizeType2(ESizeCompareType eSizeType2);
 
-	unsigned long long GetSize2() const { return m_ullSize2; }
-	void SetSize2(unsigned long long ullSize2) { m_ullSize2 = ullSize2; }
+	unsigned long long GetSize2() const;
+	void SetSize2(unsigned long long ullSize2);
 
 	// dates
-	TFileFilter::EDateType GetDateType() const { return m_eDateType; }
-	void SetDateType(TFileFilter::EDateType eDateType) { m_eDateType = eDateType; }
+	TFileFilter::EDateType GetDateType() const;
+	void SetDateType(TFileFilter::EDateType eDateType);
 
 	// date 1
-	bool GetUseDateTime1() const { return m_bUseDateTime1; }
-	void SetUseDateTime1(bool bUseDateTime1) { m_bUseDateTime1 = bUseDateTime1; }
+	bool GetUseDateTime1() const;
+	void SetUseDateTime1(bool bUseDateTime1);
 
-	TFileFilter::EDateCompareType GetDateCmpType1() const { return m_eDateCmpType1; }
-	void SetDateCmpType1(TFileFilter::EDateCompareType eCmpType1) { m_eDateCmpType1 = eCmpType1; }
+	TFileFilter::EDateCompareType GetDateCmpType1() const;
+	void SetDateCmpType1(TFileFilter::EDateCompareType eCmpType1);
 
-	bool GetUseDate1() const { return m_bUseDate1; }
-	void SetUseDate1(bool tDate1) { m_bUseDate1 = tDate1; }
+	bool GetUseDate1() const;
+	void SetUseDate1(bool tDate1);
 
-	bool GetUseTime1() const { return m_bUseTime1; }
-	void SetUseTime1(bool tTime1) { m_bUseTime1 = tTime1; }
+	bool GetUseTime1() const;
+	void SetUseTime1(bool tTime1);
 
-	const TDateTime& GetDateTime1() const { return m_tDateTime1; }
-	void SetDateTime1(const TDateTime& tDateTime1) { m_tDateTime1 = tDateTime1; }
+	const TDateTime& GetDateTime1() const;
+	void SetDateTime1(const TDateTime& tDateTime1);
 
 	// date 2
-	bool GetUseDateTime2() const { return m_bUseDateTime2; }
-	void SetUseDateTime2(bool bUseDateTime2) { m_bUseDateTime2 = bUseDateTime2; }
+	bool GetUseDateTime2() const;
+	void SetUseDateTime2(bool bUseDateTime2);
 
-	TFileFilter::EDateCompareType GetDateCmpType2() const { return m_eDateCmpType2; }
-	void SetDateCmpType2(TFileFilter::EDateCompareType eCmpType2) { m_eDateCmpType2 = eCmpType2; }
+	TFileFilter::EDateCompareType GetDateCmpType2() const;
+	void SetDateCmpType2(TFileFilter::EDateCompareType eCmpType2);
 
-	bool GetUseDate2() const { return m_bUseDate2; }
-	void SetUseDate2(bool tDate2) { m_bUseDate2 = tDate2; }
+	bool GetUseDate2() const;
+	void SetUseDate2(bool tDate2);
 
-	bool GetUseTime2() const { return m_bUseTime2; }
-	void SetUseTime2(bool tTime2) { m_bUseTime2 = tTime2; }
+	bool GetUseTime2() const;
+	void SetUseTime2(bool tTime2);
 
-	const TDateTime& GetDateTime2() const { return m_tDateTime2; }
-	void SetDateTime2(const TDateTime& tDateTime2) { m_tDateTime2 = tDateTime2; }
+	const TDateTime& GetDateTime2() const;
+	void SetDateTime2(const TDateTime& tDateTime2);
 
 	// attributes
-	bool GetUseAttributes() const { return m_bUseAttributes; }
-	void SetUseAttributes(bool bUseAttributes) { m_bUseAttributes = bUseAttributes; }
+	bool GetUseAttributes() const;
+	void SetUseAttributes(bool bUseAttributes);
 
-	int GetArchive() const { return m_iArchive; }
-	void SetArchive(int iArchive) { m_iArchive = iArchive; }
+	int GetArchive() const;
+	void SetArchive(int iArchive);
 
-	int GetReadOnly() const { return m_iReadOnly; }
-	void SetReadOnly(int iReadOnly) { m_iReadOnly = iReadOnly; }
+	int GetReadOnly() const;
+	void SetReadOnly(int iReadOnly);
 
-	int GetHidden() const { return m_iHidden; }
-	void SetHidden(int iHidden) { m_iHidden = iHidden; }
+	int GetHidden() const;
+	void SetHidden(int iHidden);
 
 	int GetSystem() const { return m_iSystem; }
 	void SetSystem(int iSystem) { m_iSystem = iSystem; }
@@ -168,49 +183,91 @@
 	bool Scan(LPCTSTR& lpszMask, LPCTSTR& lpszString) const;
 
 private:
+	enum EModifications
+	{
+		eMod_Added,
+		eMod_UseMask,
+		eMod_Mask,
+		eMod_UseExcludeMask,
+		eMod_ExcludeMask,
+		eMod_UseSize1,
+		eMod_SizeCmpType1,
+		eMod_Size1,
+		eMod_UseSize2,
+		eMod_SizeCmpType2,
+		eMod_Size2,
+		eMod_DateType,
+		eMod_UseDateTime1,
+		eMod_DateCmpType1,
+		eMod_UseDate1,
+		eMod_UseTime1,
+		eMod_DateTime1,
+		eMod_UseDateTime2,
+		eMod_DateCmpType2,
+		eMod_UseDate2,
+		eMod_UseTime2,
+		eMod_DateTime2,
+		eMod_UseAttributes,
+		eMod_AttrArchive,
+		eMod_AttrReadOnly,
+		eMod_AttrHidden,
+		eMod_AttrSystem,
+		eMod_AttrDirectory,
+
+		eMod_Last
+	};
+
+	// object identification
+	size_t m_stObjectID;
+
+	// modification management
+#pragma warning(push)
+#pragma warning(disable: 4251)
+	typedef std::bitset<eMod_Last> Bitset;
+	mutable Bitset m_setModifications;
+
 	// files mask
-	bool m_bUseMask;
-	TStringArray m_astrMask;
+	TSharedModificationTracker<bool, Bitset, eMod_UseMask> m_bUseMask;
+	TSharedModificationTracker<TStringArray, Bitset, eMod_Mask> m_astrMask;
 
 	// files mask-
-	bool m_bUseExcludeMask;
-	TStringArray m_astrExcludeMask;
+	TSharedModificationTracker<bool, Bitset, eMod_UseExcludeMask> m_bUseExcludeMask;
+	TSharedModificationTracker<TStringArray, Bitset, eMod_ExcludeMask> m_astrExcludeMask;
 
 	// size filtering
-	bool m_bUseSize1;
-	ESizeCompareType m_eSizeCmpType1;
-	unsigned long long m_ullSize1;
+	TSharedModificationTracker<bool, Bitset, eMod_UseSize1> m_bUseSize1;
+	TSharedModificationTracker<ESizeCompareType, Bitset, eMod_SizeCmpType1> m_eSizeCmpType1;
+	TSharedModificationTracker<unsigned long long, Bitset, eMod_Size1> m_ullSize1;
 
-	bool m_bUseSize2;
-	ESizeCompareType m_eSizeCmpType2;
-	unsigned long long m_ullSize2;
+	TSharedModificationTracker<bool, Bitset, eMod_UseSize2> m_bUseSize2;
+	TSharedModificationTracker<ESizeCompareType, Bitset, eMod_SizeCmpType2> m_eSizeCmpType2;
+	TSharedModificationTracker<unsigned long long, Bitset, eMod_Size2> m_ullSize2;
 
 	// date filtering
-	EDateType m_eDateType;	// created/last modified/last accessed
+	TSharedModificationTracker<EDateType, Bitset, eMod_DateType> m_eDateType;	// created/last modified/last accessed
 
-	bool m_bUseDateTime1;
-#pragma warning(push)
-#pragma warning(disable: 4251)
-	EDateCompareType m_eDateCmpType1;	// before/after
-	bool m_bUseDate1;
-	bool m_bUseTime1;
-	TDateTime m_tDateTime1;
+	TSharedModificationTracker<bool, Bitset, eMod_UseDateTime1> m_bUseDateTime1;
 
-	bool m_bUseDateTime2;
+	TSharedModificationTracker<EDateCompareType, Bitset, eMod_DateCmpType1> m_eDateCmpType1;	// before/after
+	TSharedModificationTracker<bool, Bitset, eMod_UseDate1> m_bUseDate1;
+	TSharedModificationTracker<bool, Bitset, eMod_UseTime1> m_bUseTime1;
+	TSharedModificationTracker<TDateTime, Bitset, eMod_DateTime1> m_tDateTime1;
 
-	EDateCompareType m_eDateCmpType2;
-	bool m_bUseDate2;
-	bool m_bUseTime2;
-	TDateTime m_tDateTime2;
-#pragma warning(pop)
+	TSharedModificationTracker<bool, Bitset, eMod_UseDateTime2> m_bUseDateTime2;
 
+	TSharedModificationTracker<EDateCompareType, Bitset, eMod_DateCmpType2> m_eDateCmpType2;
+	TSharedModificationTracker<bool, Bitset, eMod_UseDate2> m_bUseDate2;
+	TSharedModificationTracker<bool, Bitset, eMod_UseTime2> m_bUseTime2;
+	TSharedModificationTracker<TDateTime, Bitset, eMod_DateTime2> m_tDateTime2;
+
 	// attribute filtering
-	bool m_bUseAttributes;
-	int m_iArchive;
-	int m_iReadOnly;
-	int m_iHidden;
-	int m_iSystem;
-	int m_iDirectory;
+	TSharedModificationTracker<bool, Bitset, eMod_UseAttributes> m_bUseAttributes;
+	TSharedModificationTracker<int, Bitset, eMod_AttrArchive> m_iArchive;
+	TSharedModificationTracker<int, Bitset, eMod_AttrReadOnly> m_iReadOnly;
+	TSharedModificationTracker<int, Bitset, eMod_AttrHidden> m_iHidden;
+	TSharedModificationTracker<int, Bitset, eMod_AttrSystem> m_iSystem;
+	TSharedModificationTracker<int, Bitset, eMod_AttrDirectory> m_iDirectory;
+#pragma warning(pop)
 };
 
 END_CHCORE_NAMESPACE
Index: src/libchcore/TFileFiltersArray.cpp
===================================================================
diff -u -r960167a493c3ae7ecbdc7e8c2b91619106d7a685 -rb193a95402f2bf4c456fb9d65d111caaf6994823
--- src/libchcore/TFileFiltersArray.cpp	(.../TFileFiltersArray.cpp)	(revision 960167a493c3ae7ecbdc7e8c2b91619106d7a685)
+++ src/libchcore/TFileFiltersArray.cpp	(.../TFileFiltersArray.cpp)	(revision b193a95402f2bf4c456fb9d65d111caaf6994823)
@@ -26,6 +26,14 @@
 
 BEGIN_CHCORE_NAMESPACE
 
+TFileFiltersArray::TFileFiltersArray()
+{
+}
+
+TFileFiltersArray::~TFileFiltersArray()
+{
+}
+
 TFileFiltersArray& TFileFiltersArray::operator=(const TFileFiltersArray& rSrc)
 {
 	if(this != &rSrc)
@@ -81,18 +89,6 @@
 	return true;
 }
 
-void TFileFiltersArray::Serialize(TReadBinarySerializer& rSerializer)
-{
-	using Serializers::Serialize;
-	Serialize(rSerializer, m_vFilters);
-}
-
-void TFileFiltersArray::Serialize(TWriteBinarySerializer& rSerializer) const
-{
-	using Serializers::Serialize;
-	Serialize(rSerializer, m_vFilters);
-}
-
 bool TFileFiltersArray::IsEmpty() const
 {
 	return m_vFilters.empty();
@@ -109,7 +105,8 @@
 	if(stIndex < m_vFilters.size())
 	{
 		TFileFilter& rFilter = m_vFilters.at(stIndex);
-		rFilter = rNewFilter;
+
+		rFilter.SetData(rNewFilter);
 		return true;
 	}
 	else
@@ -130,6 +127,8 @@
 	BOOST_ASSERT(stIndex < m_vFilters.size());
 	if(stIndex < m_vFilters.size())
 	{
+		m_setRemovedObjects.Add(m_vFilters[stIndex].GetObjectID());
+
 		m_vFilters.erase(m_vFilters.begin() + stIndex);
 		return true;
 	}
@@ -144,7 +143,39 @@
 
 void TFileFiltersArray::Clear()
 {
+	BOOST_FOREACH(const TFileFilter& rFilter, m_vFilters)
+	{
+		m_setRemovedObjects.Add(rFilter.GetObjectID());
+	}
 	m_vFilters.clear();
 }
 
+void TFileFiltersArray::Store(const ISerializerContainerPtr& spContainer) const
+{
+	spContainer->DeleteRows(m_setRemovedObjects);
+
+	BOOST_FOREACH(const TFileFilter& rFilter, m_vFilters)
+	{
+		rFilter.Store(spContainer);
+	}
+}
+
+void TFileFiltersArray::Load(const ISerializerContainerPtr& spContainer)
+{
+	IColumnsDefinitionPtr spColumns = spContainer->GetColumnsDefinition();
+	if(spColumns->IsEmpty())
+		TFileFilter::SetupLoader(spColumns);
+
+	ISerializerRowReaderPtr spRowReader = spContainer->GetRowReader();
+	while(spRowReader->Next())
+	{
+		TFileFilter tFileFilter;
+		tFileFilter.Load(spRowReader);
+
+		tFileFilter.ResetModifications();
+
+		m_vFilters.push_back(tFileFilter);
+	}
+}
+
 END_CHCORE_NAMESPACE
Index: src/libchcore/TFileFiltersArray.h
===================================================================
diff -u -ra5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8 -rb193a95402f2bf4c456fb9d65d111caaf6994823
--- src/libchcore/TFileFiltersArray.h	(.../TFileFiltersArray.h)	(revision a5f396da5ed5ffb3fcd9fdf22afb5a7fd07e1ab8)
+++ src/libchcore/TFileFiltersArray.h	(.../TFileFiltersArray.h)	(revision b193a95402f2bf4c456fb9d65d111caaf6994823)
@@ -21,29 +21,29 @@
 
 #include "libchcore.h"
 #include "TFileFilter.h"
+#include "ISerializerContainer.h"
+#include "TRemovedObjects.h"
 
 BEGIN_CHCORE_NAMESPACE
 
 class TConfig;
 class TFileInfo;
 typedef boost::shared_ptr<TFileInfo> TFileInfoPtr;
-class TReadBinarySerializer;
-class TWriteBinarySerializer;
 
 class LIBCHCORE_API TFileFiltersArray
 {
 public:
-	TFileFiltersArray() {}
-	~TFileFiltersArray() {}
+	TFileFiltersArray();
+	~TFileFiltersArray();
 
 	TFileFiltersArray& operator=(const TFileFiltersArray& rSrc);
 	bool Match(const TFileInfoPtr& spInfo) const;
 
 	void StoreInConfig(TConfig& rConfig, PCTSTR pszNodeName) const;
 	bool ReadFromConfig(const TConfig& rConfig, PCTSTR pszNodeName);
 
-	void Serialize(TReadBinarySerializer& rSerializer);
-	void Serialize(TWriteBinarySerializer& rSerializer) const;
+	void Store(const ISerializerContainerPtr& spContainer) const;
+	void Load(const ISerializerContainerPtr& spContainer);
 
 	bool IsEmpty() const;
 
@@ -60,6 +60,7 @@
 #pragma warning(disable: 4251)
 	std::vector<TFileFilter> m_vFilters;
 #pragma warning(pop)
+	TRemovedObjects m_setRemovedObjects;
 };
 
 END_CHCORE_NAMESPACE
Index: src/libchcore/TSQLiteTaskSchema.cpp
===================================================================
diff -u -rb1e03eb232a784d6e2d40f67cbbbb33be0972228 -rb193a95402f2bf4c456fb9d65d111caaf6994823
--- src/libchcore/TSQLiteTaskSchema.cpp	(.../TSQLiteTaskSchema.cpp)	(revision b1e03eb232a784d6e2d40f67cbbbb33be0972228)
+++ src/libchcore/TSQLiteTaskSchema.cpp	(.../TSQLiteTaskSchema.cpp)	(revision b193a95402f2bf4c456fb9d65d111caaf6994823)
@@ -55,6 +55,17 @@
 		tStatement.Prepare(_T("CREATE TABLE task_config(id BIGINT UNIQUE, name varchar(256) NOT NULL, node_order INT NOT NULL, value varchar(32768) NOT NULL)"));
 		tStatement.Step();
 
+		tStatement.Prepare(_T("CREATE TABLE filters(id BIGINT UNIQUE, use_mask INT NOT NULL, mask varchar(32768) NOT NULL, ")
+			_T("use_exclude_mask INT NOT NULL, exclude_mask varchar(32768) NOT NULL, ")
+			_T("use_size_1 INT NOT NULL, compare_type_1 INT NOT NULL, size_1 BIGINT NOT NULL, ")
+			_T("use_size_2 INT NOT NULL, compare_type_2 INT NOT NULL, size_2 BIGINT NOT NULL, ")
+			_T("date_type INT NOT NULL,")
+			_T("use_date_time_1 INT NOT NULL, date_compare_type_1 INT NOT NULL, use_date_1 INT NOT NULL, use_time_1 INT NOT NULL, datetime_1 varchar(64) NOT NULL, ")
+			_T("use_date_time_2 INT NOT NULL, date_compare_type_2 INT NOT NULL, use_date_2 INT NOT NULL, use_time_2 INT NOT NULL, datetime_2 varchar(64) NOT NULL, ")
+			_T("use_attributes INT NOT NULL, attr_archive INT NOT NULL, attr_ro INT NOT NULL, attr_hidden INT NOT NULL, attr_system INT NOT NULL, attr_directory INT NOT NULL")
+			_T(")"));
+		tStatement.Step();
+
 		// and finally set the database version to current one
 		tVersion.SetVersion(1);
 	}
Index: src/libchcore/TSharedModificationTracker.h
===================================================================
diff -u -ra5aa3c3cb78f3767641de2627d1a49a1dc35b429 -rb193a95402f2bf4c456fb9d65d111caaf6994823
--- src/libchcore/TSharedModificationTracker.h	(.../TSharedModificationTracker.h)	(revision a5aa3c3cb78f3767641de2627d1a49a1dc35b429)
+++ src/libchcore/TSharedModificationTracker.h	(.../TSharedModificationTracker.h)	(revision b193a95402f2bf4c456fb9d65d111caaf6994823)
@@ -38,9 +38,15 @@
 		m_tValue(rSrc.m_tValue),
 		m_rBitset(rSrc.m_rBitset)
 	{
-		m_rBitset[ChangeBit] = true;
 	}
 
+	TSharedModificationTracker(const TSharedModificationTracker<T, Bitset, ChangeBit>& rSrc, Bitset& rBitset) :
+		m_tValue(rSrc.m_tValue),
+		m_rBitset(rBitset)
+	{
+		m_rBitset[ChangeBit] = rBitset[ChangeBit];
+	}
+
 	template<class V>
 	TSharedModificationTracker(Bitset& rBitset, const V& rValue) :
 		m_tValue(rValue),
@@ -54,7 +60,8 @@
 		if(this != &rValue)
 		{
 			m_tValue = rValue.m_tValue;
-			m_rBitset = rValue.m_rBitset;
+			if(m_tValue != rValue.m_tValue)
+				m_rBitset[ChangeBit] = true;
 		}
 
 		return *this;
Index: src/libchcore/TStringArray.cpp
===================================================================
diff -u -r548382442cbf7bed7f744b279ce3f66b54992724 -rb193a95402f2bf4c456fb9d65d111caaf6994823
--- src/libchcore/TStringArray.cpp	(.../TStringArray.cpp)	(revision 548382442cbf7bed7f744b279ce3f66b54992724)
+++ src/libchcore/TStringArray.cpp	(.../TStringArray.cpp)	(revision b193a95402f2bf4c456fb9d65d111caaf6994823)
@@ -214,4 +214,34 @@
 	Serializers::Serialize(rSerializer, m_vItems);
 }
 
+bool TStringArray::operator==(const TStringArray& rSrc) const
+{
+	if(rSrc.GetCount() != GetCount())
+		return false;
+
+	size_t stCount = GetCount();
+	while(stCount-- > 0)
+	{
+		if(m_vItems[stCount] != rSrc.m_vItems[stCount])
+			return false;
+	}
+
+	return true;
+}
+
+bool TStringArray::operator!=(const TStringArray& rSrc) const
+{
+	if(rSrc.GetCount() != GetCount())
+		return true;
+
+	size_t stCount = GetCount();
+	while(stCount-- > 0)
+	{
+		if(m_vItems[stCount] != rSrc.m_vItems[stCount])
+			return true;
+	}
+
+	return false;
+}
+
 END_CHCORE_NAMESPACE
Index: src/libchcore/TStringArray.h
===================================================================
diff -u -rde5a63babb2991c808333230014a4f2e6cc8b7b2 -rb193a95402f2bf4c456fb9d65d111caaf6994823
--- src/libchcore/TStringArray.h	(.../TStringArray.h)	(revision de5a63babb2991c808333230014a4f2e6cc8b7b2)
+++ src/libchcore/TStringArray.h	(.../TStringArray.h)	(revision b193a95402f2bf4c456fb9d65d111caaf6994823)
@@ -95,6 +95,9 @@
 	TStringArray();
 	~TStringArray();
 
+	bool operator==(const TStringArray& rSrc) const;
+	bool operator!=(const TStringArray& rSrc) const;
+
 	void Add(const TString& str);
 	void InsertAt(size_t stIndex, const TString& str);
 	void SetAt(size_t stIndex, const TString& str);
Index: src/libchcore/TSubTaskContext.cpp
===================================================================
diff -u -ra7834ba278464cb62739f22d35f9bc16269706a1 -rb193a95402f2bf4c456fb9d65d111caaf6994823
--- src/libchcore/TSubTaskContext.cpp	(.../TSubTaskContext.cpp)	(revision a7834ba278464cb62739f22d35f9bc16269706a1)
+++ src/libchcore/TSubTaskContext.cpp	(.../TSubTaskContext.cpp)	(revision b193a95402f2bf4c456fb9d65d111caaf6994823)
@@ -24,10 +24,12 @@
 #include "TSubTaskContext.h"
 #include "ErrorCodes.h"
 #include "TCoreException.h"
+#include "TFileFiltersArray.h"
 
 BEGIN_CHCORE_NAMESPACE
 
-TSubTaskContext::TSubTaskContext(TConfig& rConfig, const TBasePathDataContainerPtr& spBasePaths, TFileInfoArray& rFilesCache,
+TSubTaskContext::TSubTaskContext(TConfig& rConfig, const TBasePathDataContainerPtr& spBasePaths,
+								const TFileFiltersArray& rFilters, TFileInfoArray& rFilesCache,
 								TTaskConfigTracker& rCfgTracker, icpf::log_file& rLog, const IFeedbackHandlerPtr& spFeedbackHandler,
 								TWorkerThreadController& rThreadController, TLocalFilesystem& rfsLocal) :
 	m_rConfig(rConfig),
@@ -39,7 +41,8 @@
 	m_rLog(rLog),
 	m_spFeedbackHandler(spFeedbackHandler),
 	m_rThreadController(rThreadController),
-	m_rfsLocal(rfsLocal)
+	m_rfsLocal(rfsLocal),
+	m_rFilters(rFilters)
 {
 }
 
@@ -140,4 +143,9 @@
 	return m_rfsLocal;
 }
 
+const TFileFiltersArray& TSubTaskContext::GetFilters() const
+{
+	return m_rFilters;
+}
+
 END_CHCORE_NAMESPACE
Index: src/libchcore/TSubTaskContext.h
===================================================================
diff -u -ra5aa3c3cb78f3767641de2627d1a49a1dc35b429 -rb193a95402f2bf4c456fb9d65d111caaf6994823
--- src/libchcore/TSubTaskContext.h	(.../TSubTaskContext.h)	(revision a5aa3c3cb78f3767641de2627d1a49a1dc35b429)
+++ src/libchcore/TSubTaskContext.h	(.../TSubTaskContext.h)	(revision b193a95402f2bf4c456fb9d65d111caaf6994823)
@@ -43,16 +43,18 @@
 class TTaskBasicProgressInfo;
 class TFileInfoArray;
 class TConfig;
+class TFileFiltersArray;
 
 ///////////////////////////////////////////////////////////////////////////
 // TSubTaskContext
 
 class LIBCHCORE_API TSubTaskContext
 {
 public:
-	TSubTaskContext(TConfig& rConfig, const TBasePathDataContainerPtr& spBasePaths, TFileInfoArray& rFilesCache,
-		TTaskConfigTracker& rCfgTracker, icpf::log_file& rLog, const IFeedbackHandlerPtr& spFeedbackHandler,
-		TWorkerThreadController& rThreadController, TLocalFilesystem& rfsLocal);
+	TSubTaskContext(TConfig& rConfig, const TBasePathDataContainerPtr& spBasePaths,
+					const TFileFiltersArray& rFilters, TFileInfoArray& rFilesCache,
+					TTaskConfigTracker& rCfgTracker, icpf::log_file& rLog, const IFeedbackHandlerPtr& spFeedbackHandler,
+					TWorkerThreadController& rThreadController, TLocalFilesystem& rfsLocal);
 	~TSubTaskContext();
 
 	TConfig& GetConfig();
@@ -63,6 +65,7 @@
 
 	TBasePathDataContainerPtr GetBasePaths() const;
 
+	const TFileFiltersArray& GetFilters() const;
 	TFileInfoArray& GetFilesCache();
 	const TFileInfoArray& GetFilesCache() const;
 
@@ -98,6 +101,8 @@
 	TBasePathDataContainerPtr m_spBasePaths;
 #pragma warning(pop)
 
+	const TFileFiltersArray& m_rFilters;
+
 	// data on which to operate
 	TFileInfoArray& m_rFilesCache;
 
Index: src/libchcore/TSubTaskFastMove.cpp
===================================================================
diff -u -ra7834ba278464cb62739f22d35f9bc16269706a1 -rb193a95402f2bf4c456fb9d65d111caaf6994823
--- src/libchcore/TSubTaskFastMove.cpp	(.../TSubTaskFastMove.cpp)	(revision a7834ba278464cb62739f22d35f9bc16269706a1)
+++ src/libchcore/TSubTaskFastMove.cpp	(.../TSubTaskFastMove.cpp)	(revision b193a95402f2bf4c456fb9d65d111caaf6994823)
@@ -120,6 +120,7 @@
 	TBasePathDataContainerPtr spBasePaths = GetContext().GetBasePaths();
 	const TConfig& rConfig = GetContext().GetConfig();
 	TSmartPath pathDestination = GetContext().GetDestinationPath();
+	const TFileFiltersArray& rafFilters = GetContext().GetFilters();
 
 	rLog.logi(_T("Performing initial fast-move operation..."));
 
@@ -131,10 +132,6 @@
 	m_tSubTaskStats.SetProcessedSize(0);
 	m_tSubTaskStats.SetCurrentPath(TString());
 
-	// read filtering options
-	TFileFiltersArray afFilters;
-	GetTaskPropValue<eTO_Filters>(rConfig, afFilters);
-
 	bool bIgnoreDirs = GetTaskPropValue<eTO_IgnoreDirectories>(rConfig);
 	bool bForceDirectories = GetTaskPropValue<eTO_CreateDirectoriesRelativeToRoot>(rConfig);
 
@@ -209,7 +206,7 @@
 			continue;
 
 		// does it match the input filter?
-		if(!spFileInfo->IsDirectory() && !afFilters.Match(spFileInfo))
+		if(!spFileInfo->IsDirectory() && !rafFilters.Match(spFileInfo))
 		{
 			spBasePath->SetSkipFurtherProcessing(true);
 			continue;
Index: src/libchcore/TSubTaskScanDirectory.cpp
===================================================================
diff -u -ra7834ba278464cb62739f22d35f9bc16269706a1 -rb193a95402f2bf4c456fb9d65d111caaf6994823
--- src/libchcore/TSubTaskScanDirectory.cpp	(.../TSubTaskScanDirectory.cpp)	(revision a7834ba278464cb62739f22d35f9bc16269706a1)
+++ src/libchcore/TSubTaskScanDirectory.cpp	(.../TSubTaskScanDirectory.cpp)	(revision b193a95402f2bf4c456fb9d65d111caaf6994823)
@@ -122,6 +122,7 @@
 	TWorkerThreadController& rThreadController = GetContext().GetThreadController();
 	TBasePathDataContainerPtr spBasePaths = GetContext().GetBasePaths();
 	const TConfig& rConfig = GetContext().GetConfig();
+	const TFileFiltersArray& rafFilters = GetContext().GetFilters();
 
 	rLog.logi(_T("Searching for files..."));
 
@@ -139,10 +140,6 @@
 	// delete the content of rFilesCache
 	rFilesCache.Clear();
 
-	// read filtering options
-	TFileFiltersArray afFilters;
-	GetTaskPropValue<eTO_Filters>(rConfig, afFilters);
-
 	bool bIgnoreDirs = GetTaskPropValue<eTO_IgnoreDirectories>(rConfig);
 	bool bForceDirectories = GetTaskPropValue<eTO_CreateDirectoriesRelativeToRoot>(rConfig);
 
@@ -239,7 +236,7 @@
 			strFormat.Replace(_t("%path"), spFileInfo->GetFullFilePath().ToString());
 			rLog.logi(strFormat);
 
-			ScanDirectory(spFileInfo->GetFullFilePath(), spBasePath, true, !bIgnoreDirs || bForceDirectories, afFilters);
+			ScanDirectory(spFileInfo->GetFullFilePath(), spBasePath, true, !bIgnoreDirs || bForceDirectories, rafFilters);
 
 			// check for kill need
 			if(rThreadController.KillRequested())
@@ -253,7 +250,7 @@
 		else
 		{
 			// add file info if passes filters
-			if(afFilters.Match(spFileInfo))
+			if(rafFilters.Match(spFileInfo))
 				rFilesCache.AddFileInfo(spFileInfo);
 
 			// log
@@ -283,7 +280,8 @@
 	m_tSubTaskStats.GetSnapshot(spStats);
 }
 
-int TSubTaskScanDirectories::ScanDirectory(TSmartPath pathDirName, const TBasePathDataPtr& spBasePathData, bool bRecurse, bool bIncludeDirs, TFileFiltersArray& afFilters)
+int TSubTaskScanDirectories::ScanDirectory(TSmartPath pathDirName, const TBasePathDataPtr& spBasePathData,
+										   bool bRecurse, bool bIncludeDirs, const TFileFiltersArray& afFilters)
 {
 	TFileInfoArray& rFilesCache = GetContext().GetFilesCache();
 	TWorkerThreadController& rThreadController = GetContext().GetThreadController();
Index: src/libchcore/TSubTaskScanDirectory.h
===================================================================
diff -u -ra7834ba278464cb62739f22d35f9bc16269706a1 -rb193a95402f2bf4c456fb9d65d111caaf6994823
--- src/libchcore/TSubTaskScanDirectory.h	(.../TSubTaskScanDirectory.h)	(revision a7834ba278464cb62739f22d35f9bc16269706a1)
+++ src/libchcore/TSubTaskScanDirectory.h	(.../TSubTaskScanDirectory.h)	(revision b193a95402f2bf4c456fb9d65d111caaf6994823)
@@ -78,7 +78,8 @@
 	virtual void GetStatsSnapshot(TSubTaskStatsSnapshotPtr& spStats) const;
 
 private:
-	int ScanDirectory(TSmartPath pathDirName, const TBasePathDataPtr& spBasePathData, bool bRecurse, bool bIncludeDirs, TFileFiltersArray& afFilters);
+	int ScanDirectory(TSmartPath pathDirName, const TBasePathDataPtr& spBasePathData,
+					  bool bRecurse, bool bIncludeDirs, const TFileFiltersArray& afFilters);
 
 private:
 #pragma warning(push)
Index: src/libchcore/TTask.cpp
===================================================================
diff -u -rb1e03eb232a784d6e2d40f67cbbbb33be0972228 -rb193a95402f2bf4c456fb9d65d111caaf6994823
--- src/libchcore/TTask.cpp	(.../TTask.cpp)	(revision b1e03eb232a784d6e2d40f67cbbbb33be0972228)
+++ src/libchcore/TTask.cpp	(.../TTask.cpp)	(revision b193a95402f2bf4c456fb9d65d111caaf6994823)
@@ -50,7 +50,8 @@
 	m_files(),
 	m_bForce(false),
 	m_bContinue(false),
-	m_tSubTaskContext(m_tConfiguration, m_spSrcPaths, m_files, m_cfgTracker, m_log, spFeedbackHandler, m_workerThread, m_fsLocal),
+	m_tSubTaskContext(m_tConfiguration, m_spSrcPaths, m_afFilters, m_files,
+		m_cfgTracker, m_log, spFeedbackHandler, m_workerThread, m_fsLocal),
 	m_tSubTasksArray(),
 	m_spSerializer(spSerializer)
 {
@@ -68,6 +69,7 @@
 	m_tBaseData.SetDestinationPath(rTaskDefinition.GetDestinationPath());
 	m_tConfiguration = rTaskDefinition.GetConfiguration();
 	*m_spSrcPaths = rTaskDefinition.GetSourcePaths();
+	m_afFilters = rTaskDefinition.GetFilters();
 	m_tBaseData.SetTaskName(rTaskDefinition.GetTaskName());
 
 	m_tSubTasksArray.Init(rTaskDefinition.GetOperationPlan(), m_tSubTaskContext);
@@ -143,6 +145,9 @@
 
 		spContainer = m_spSerializer->GetContainer(_T("task_config"));
 		m_tConfiguration.Load(spContainer);
+
+		spContainer = m_spSerializer->GetContainer(_T("filters"));
+		m_afFilters.Load(spContainer);
 	}
 }
 
@@ -165,6 +170,9 @@
 
 		spContainer = m_spSerializer->GetContainer(_T("task_config"));
 		m_tConfiguration.Store(spContainer);
+
+		spContainer = m_spSerializer->GetContainer(_T("filters"));
+		m_afFilters.Store(spContainer);
 	}
 
 	m_spSerializer->Flush();
Index: src/libchcore/TTaskConfigTracker.cpp
===================================================================
diff -u -rb1e03eb232a784d6e2d40f67cbbbb33be0972228 -rb193a95402f2bf4c456fb9d65d111caaf6994823
--- src/libchcore/TTaskConfigTracker.cpp	(.../TTaskConfigTracker.cpp)	(revision b1e03eb232a784d6e2d40f67cbbbb33be0972228)
+++ src/libchcore/TTaskConfigTracker.cpp	(.../TTaskConfigTracker.cpp)	(revision b193a95402f2bf4c456fb9d65d111caaf6994823)
@@ -243,16 +243,14 @@
 		return eTO_AlternateFilenameFormatString_AfterFirst;
 	else if(strOption == TaskPropData<eTO_AlternateFilenameFormatString_AfterFirst>::GetPropertyName())
 		return eTO_AlternateFilenameFormatString_First;
-	else if(strOption == TaskPropData<eTO_Filters>::GetPropertyName())
-		return eTO_Filters;
 	else
 	{
 		BOOST_ASSERT(false);		// unhandled case
 		THROW_CORE_EXCEPTION(eErr_UnhandledCase);
 	}
 
 	// add new elements before this one
-	BOOST_STATIC_ASSERT(eTO_Last == eTO_Filters + 1);
+	BOOST_STATIC_ASSERT(eTO_Last == eTO_AlternateFilenameFormatString_AfterFirst + 1);
 }
 
 END_CHCORE_NAMESPACE
Index: src/libchcore/TTaskConfiguration.h
===================================================================
diff -u -rfdf4929dc7df1376ed439b7271765f1a4ca31de6 -rb193a95402f2bf4c456fb9d65d111caaf6994823
--- src/libchcore/TTaskConfiguration.h	(.../TTaskConfiguration.h)	(revision fdf4929dc7df1376ed439b7271765f1a4ca31de6)
+++ src/libchcore/TTaskConfiguration.h	(.../TTaskConfiguration.h)	(revision b193a95402f2bf4c456fb9d65d111caaf6994823)
@@ -57,8 +57,6 @@
 	eTO_AlternateFilenameFormatString_First,
 	eTO_AlternateFilenameFormatString_AfterFirst,
 
-	eTO_Filters,
-
 	// add new elements before this one
 	eTO_Last
 };
@@ -123,8 +121,6 @@
 TASK_PROPERTY(eTO_CreateDirectoriesRelativeToRoot, bool, _T("Operation.CreateDirectoriesRelativeToRoot"), false);
 TASK_PROPERTY(eTO_IgnoreDirectories, bool, _T("Operation.IgnoreDirectories"), false);
 
-TASK_PROPERTY(eTO_Filters, chcore::TFileFiltersArray, _T("Operation.Filtering"), TFileFiltersArray());
-
 // Naming settings
 TASK_PROPERTY(eTO_AlternateFilenameFormatString_First, TString, _T("Naming.AlternateFilenameFormatFirst"), _T("Copy of %name"));
 TASK_PROPERTY(eTO_AlternateFilenameFormatString_AfterFirst, TString, _T("Naming.AlternateFilenameFormatAfterFirst"), _T("Copy (%count) of %name"));
Index: src/libchcore/TTaskDefinition.cpp
===================================================================
diff -u -rb1e03eb232a784d6e2d40f67cbbbb33be0972228 -rb193a95402f2bf4c456fb9d65d111caaf6994823
--- src/libchcore/TTaskDefinition.cpp	(.../TTaskDefinition.cpp)	(revision b1e03eb232a784d6e2d40f67cbbbb33be0972228)
+++ src/libchcore/TTaskDefinition.cpp	(.../TTaskDefinition.cpp)	(revision b193a95402f2bf4c456fb9d65d111caaf6994823)
@@ -47,6 +47,7 @@
 TTaskDefinition::TTaskDefinition(const TTaskDefinition& rSrc) :
 	m_strTaskName(rSrc.m_strTaskName),
 	m_vSourcePaths(rSrc.m_vSourcePaths),
+	m_afFilters(rSrc.m_afFilters),
 	m_pathDestinationPath(rSrc.m_pathDestinationPath),
 	m_tOperationPlan(rSrc.m_tOperationPlan),
 	m_ullTaskVersion(rSrc.m_ullTaskVersion),
@@ -65,6 +66,7 @@
 	{
 		m_strTaskName = rSrc.m_strTaskName;
 		m_vSourcePaths = rSrc.m_vSourcePaths;
+		m_afFilters = rSrc.m_afFilters;
 		m_pathDestinationPath = rSrc.m_pathDestinationPath;
 		m_tOperationPlan = rSrc.m_tOperationPlan;
 		m_ullTaskVersion = rSrc.m_ullTaskVersion;
@@ -173,6 +175,7 @@
 	m_strTaskName.Clear();
 	m_vSourcePaths.Clear();
 	m_pathDestinationPath.Clear();
+	m_afFilters.Clear();
 
 	m_tConfiguration.Clear();
 
@@ -194,6 +197,8 @@
 	if(!GetConfigValue(tTaskInfo, _T("TaskDefinition.SourcePaths.Path"), m_vSourcePaths) || m_vSourcePaths.IsEmpty())
 		THROW_CORE_EXCEPTION(eErr_MissingXmlData);
 
+	GetConfigValue(tTaskInfo, _T("TaskDefinition.Filters"), m_afFilters);
+
 	// destination path
 	if(!GetConfigValue(tTaskInfo, _T("TaskDefinition.DestinationPath"), m_pathDestinationPath) || m_pathDestinationPath.IsEmpty())
 		THROW_CORE_EXCEPTION(eErr_MissingXmlData);
@@ -237,6 +242,7 @@
 
 	// basic information
 	SetConfigValue(tTaskInfo, _T("TaskDefinition.SourcePaths.Path"), m_vSourcePaths);
+	SetConfigValue(tTaskInfo, _T("TaskDefinition.Filters"), m_afFilters);
 	SetConfigValue(tTaskInfo, _T("TaskDefinition.DestinationPath"), m_pathDestinationPath);
 
 	int iOperation = m_tOperationPlan.GetOperationType();
@@ -280,6 +286,8 @@
 	if(!GetConfigValue(tTaskInfo, _T("TaskDefinition.SourcePaths.Path"), m_vSourcePaths) || m_vSourcePaths.IsEmpty())
 		THROW_CORE_EXCEPTION(eErr_MissingXmlData);
 
+	GetConfigValue(tTaskInfo, _T("TaskDefinition.Filters"), m_afFilters);
+
 	// destination path
 	if(!GetConfigValue(tTaskInfo, _T("TaskDefinition.DestinationPath"), m_pathDestinationPath) || m_pathDestinationPath.IsEmpty())
 		THROW_CORE_EXCEPTION(eErr_MissingXmlData);
@@ -312,4 +320,19 @@
 	tTaskInfo.ExtractSubConfig(_T("TaskDefinition.TaskSettings"), m_tConfiguration);
 }
 
+const TFileFiltersArray& TTaskDefinition::GetFilters() const
+{
+	return m_afFilters;
+}
+
+TFileFiltersArray& TTaskDefinition::GetFilters()
+{
+	return m_afFilters;
+}
+
+void TTaskDefinition::SetFilters(const TFileFiltersArray& rFilters)
+{
+	m_afFilters = rFilters;
+}
+
 END_CHCORE_NAMESPACE
Index: src/libchcore/TTaskDefinition.h
===================================================================
diff -u -rb1e03eb232a784d6e2d40f67cbbbb33be0972228 -rb193a95402f2bf4c456fb9d65d111caaf6994823
--- src/libchcore/TTaskDefinition.h	(.../TTaskDefinition.h)	(revision b1e03eb232a784d6e2d40f67cbbbb33be0972228)
+++ src/libchcore/TTaskDefinition.h	(.../TTaskDefinition.h)	(revision b193a95402f2bf4c456fb9d65d111caaf6994823)
@@ -27,6 +27,7 @@
 #include "TConfig.h"
 #include "TPath.h"
 #include "TPathContainer.h"
+#include "TFileFiltersArray.h"
 
 BEGIN_CHCORE_NAMESPACE
 
@@ -57,6 +58,11 @@
 
 	void ClearSourcePaths();
 
+	// filters
+	const TFileFiltersArray& GetFilters() const;
+	TFileFiltersArray& GetFilters();
+	void SetFilters(const TFileFiltersArray& rFilters);
+
 	// Destination path
 	void SetDestinationPath(const TSmartPath& pathDestination);
 	TSmartPath GetDestinationPath() const;
@@ -83,6 +89,7 @@
 	// basic information
 	TPathContainer m_vSourcePaths;
 	TSmartPath m_pathDestinationPath;
+	TFileFiltersArray m_afFilters;
 
 	TOperationPlan m_tOperationPlan;			///< Describes the operation along with sub-operations to be performed on the task input data