Index: DirectShowFilters/TsWriter/MPTSWriter.vcproj
===================================================================
--- DirectShowFilters/TsWriter/MPTSWriter.vcproj	(revision 27484)
+++ DirectShowFilters/TsWriter/MPTSWriter.vcproj	(working copy)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="Windows-1252"?>
 <VisualStudioProject
 	ProjectType="Visual C++"
-	Version="9,00"
+	Version="9.00"
 	Name="TsWriter"
 	ProjectGUID="{FCF30D16-2C9E-4429-B605-4ACA43023E71}"
 	RootNamespace="MPTSWriter"
@@ -317,6 +317,30 @@
 					>
 				</File>
 				<File
+					RelativePath=".\source\SkyChannelDecoder.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\source\SkyChannelParser.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\source\SkyEpgParser.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\source\SkyEpgSummaryDecoder.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\source\SkyEpgTitleDecoder.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\source\SkyManager.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\source\VirtualChannelTableParser.cpp"
 					>
 				</File>
@@ -360,6 +384,22 @@
 					RelativePath=".\source\EnterCriticalSection.cpp"
 					>
 				</File>
+				<File
+					RelativePath=".\source\HuffmanBranchNode.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\source\HuffmanLeafNode.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\source\HuffmanNode.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\source\HuffmanTree.cpp"
+					>
+				</File>
 			</Filter>
 		</Filter>
 		<Filter
@@ -470,6 +510,30 @@
 					>
 				</File>
 				<File
+					RelativePath=".\source\SkyChannelDecoder.h"
+					>
+				</File>
+				<File
+					RelativePath=".\source\SkyChannelParser.h"
+					>
+				</File>
+				<File
+					RelativePath=".\source\SkyEpgParser.h"
+					>
+				</File>
+				<File
+					RelativePath=".\source\SkyEpgSummaryDecoder.h"
+					>
+				</File>
+				<File
+					RelativePath=".\source\SkyEpgTitleDecoder.h"
+					>
+				</File>
+				<File
+					RelativePath=".\source\SkyManager.h"
+					>
+				</File>
+				<File
 					RelativePath=".\source\VirtualChannelTableParser.h"
 					>
 				</File>
@@ -501,6 +565,26 @@
 					RelativePath=".\source\EnterCriticalSection.h"
 					>
 				</File>
+				<File
+					RelativePath=".\source\HuffmanBranchNode.h"
+					>
+				</File>
+				<File
+					RelativePath=".\source\HuffmanLeafNode.h"
+					>
+				</File>
+				<File
+					RelativePath=".\source\HuffmanNode.h"
+					>
+				</File>
+				<File
+					RelativePath=".\source\HuffmanTree.h"
+					>
+				</File>
+				<File
+					RelativePath=".\source\SkyThemes.h"
+					>
+				</File>
 			</Filter>
 			<Filter
 				Name="SHARED"
Index: DirectShowFilters/TsWriter/source/EpgScanner.cpp
===================================================================
--- DirectShowFilters/TsWriter/source/EpgScanner.cpp	(revision 27484)
+++ DirectShowFilters/TsWriter/source/EpgScanner.cpp	(working copy)
@@ -56,6 +56,7 @@
 	m_bGrabbing=false;
 	m_epgParser.Reset();
   m_mhwParser.Reset();
+	skyManager.Reset();
 	return S_OK;
 }
 
@@ -66,6 +67,7 @@
 	m_bGrabbing=false;
 	m_epgParser.AbortGrabbing();
 	m_mhwParser.AbortGrabbing();
+	skyManager.DeActivateEpgGrabber();
 	if (m_pCallBack!=NULL)
 	{
 		LogDebug("epg: do callback");
@@ -277,6 +279,113 @@
 	return S_OK;
 }
 
+//	Activates the Sky epg grabber
+STDMETHODIMP CEpgScanner::ActivateSkyEpgGrabber(UINT activateCountryId)
+{
+	CEnterCriticalSection enter(m_section);
+	try
+	{
+		skyManager.ActivateEpgGrabber(activateCountryId);
+		m_bGrabbing=true;
+	}
+	catch(...)
+	{
+		LogDebug("CEpgScanner::ActivateSkyEpgGrabber() - Exception when activating Sky Epg grabber");
+	}
+	return S_OK;
+}
+
+//	Gets if the sky epg grabber is active
+STDMETHODIMP CEpgScanner::IsSkyEpgGrabberActive(byte* active)
+{
+		LogDebug("CEpgScanner::IsSkyEpgGrabberActive()");
+	CEnterCriticalSection enter(m_section);
+	try
+	{
+		*active = (skyManager.IsEpgGrabbingActive() ? 1 : 0);
+	}
+	catch(...)
+	{
+		LogDebug("CEpgScanner::IsSkyEpgGrabberActive() - Exception");
+	}
+	return S_OK;
+}
+
+//	Gets if the sky epg is ready to be retrieved
+STDMETHODIMP CEpgScanner::IsSkyEpgReady(byte* ready)
+{
+		LogDebug("CEpgScanner::IsSkyEpgReady()");
+	CEnterCriticalSection enter(m_section);
+	try
+	{
+		*ready = (skyManager.IsEpgGrabbingFinished() ? 1 : 0);
+	}
+	catch(...)
+	{
+		LogDebug("CEpgScanner::ActivateSkyEpgGrabber() - Exception");
+	}
+	return S_OK;
+}
+//	Gets if the sky epg grabbing has been aborted
+STDMETHODIMP CEpgScanner::HasSkyEpgAborted(byte* aborted)
+{
+	LogDebug("CEpgScanner::HasSkyEpgAborted()");
+	CEnterCriticalSection enter(m_section);
+	try
+	{
+		*aborted = (skyManager.HasEpgGrabbingAborted() ? 1 : 0);
+	}
+	catch(...)
+	{
+		LogDebug("CEpgScanner::HasSkyEpgAborted() - Exception");
+	}
+	return S_OK;
+}
+//	Resets the epg retrieval
+STDMETHODIMP CEpgScanner::ResetSkyEpgRetrieval()
+{
+		LogDebug("CEpgScanner::ResetEpgRetrieval()");
+	CEnterCriticalSection enter(m_section);
+	try
+	{
+		skyManager.ResetEpgRetrieval();
+	}
+	catch(...)
+	{
+		LogDebug("CEpgScanner::ResetEpgRetrieval() - Exception when resetting epg retrieval for Sky");
+	}
+	return S_OK;
+}
+//	Gets the next Sky epg channel
+STDMETHODIMP CEpgScanner::GetNextSkyEpgChannel(unsigned char* isLastChannel, unsigned short* channelId, unsigned short* networkId, unsigned short* transportId, unsigned short* serviceId)
+{
+	try
+	{
+		skyManager.GetNextSkyEpgChannel(isLastChannel, channelId, networkId, transportId, serviceId);
+	}
+	catch(...)
+	{
+		LogDebug("CEpgScanner::GetNextSkyEpgChannel() - Exception when retrieving next Sky epg channel");
+	}
+
+	return S_OK;
+}
+
+//	Gets the next Sky epg channel event
+STDMETHODIMP CEpgScanner::GetNextSkyEpgChannelEvent(unsigned char* isLastChannelEvent, unsigned short* eventId, unsigned short* mjdStart, unsigned int* startTime, unsigned int* duration, unsigned char** title, unsigned char** summary, unsigned char** theme, unsigned short* seriesId, byte* seriesTermination)
+{
+	try
+	{
+		skyManager.GetNextSkyEpgChannelEvent(isLastChannelEvent, eventId, mjdStart, startTime, duration, title, summary, theme, seriesId, seriesTermination);
+	}
+	catch(...)
+	{
+		LogDebug("CEpgScanner::GetNextSkyEpgChannelEvent() - Exception when retrieving next Sky epg channel event");
+	}
+
+	return S_OK;
+}
+
 bool CEpgScanner::IsEPG_PID(int pid)
 {
 	return (pid==PID_EPG || 
@@ -295,34 +404,82 @@
 
 bool CEpgScanner::IsEIT_PID(int pid)
 {
-	return (IsEPG_PID(pid) || IsMHW_PID(pid));
+	return (IsEPG_PID(pid) || IsMHW_PID(pid)) || IsSkyEpg_PID(pid);
 }
 
+//	Does the pid carry Sky Epg data?
+bool CEpgScanner::IsSkyEpg_PID(int pid)
+{
+	return skyManager.DoesPidCarryChannelNetworkData(pid) || skyManager.DoesPidCarryEpgData(pid);
+}
+
 void CEpgScanner::OnTsPacket(byte* tsPacket)
 {
   if (!m_bGrabbing) return;
 	try
 	{
 		int pid=((tsPacket[1] & 0x1F) <<8)+tsPacket[2];
-		if (!IsEIT_PID(pid)) return;
+
+		if (!IsEIT_PID(pid)) 
+			return;
+		
+		m_header.Decode(tsPacket);
+		CEnterCriticalSection enter(m_section);
+
+		if (IsEPG_PID(pid))
+			m_epgParser.OnTsPacket(m_header, tsPacket);
+		else if(IsMHW_PID(pid))
+			m_mhwParser.OnTsPacket(m_header, tsPacket);
+		else if(IsSkyEpg_PID(pid))
+			skyManager.OnTsPacket(m_header, tsPacket);
+
+		bool isSkyEpgGrabberActive = skyManager.IsEpgGrabbingActive();
+
+		//	If sky is active, we can ignore the other grabbers
+		if(isSkyEpgGrabberActive)
 		{
-			m_header.Decode(tsPacket);
-			CEnterCriticalSection enter(m_section);
-			if (IsEPG_PID(pid))
-				m_epgParser.OnTsPacket(m_header,tsPacket);
-			else
-				m_mhwParser.OnTsPacket(m_header,tsPacket);
-			if (m_epgParser.IsEPGReady() && m_mhwParser.IsEPGReady())
+			//	If sky finished or aborted?
+			if(skyManager.IsEpgGrabbingFinished())
 			{
 				LogDebug("epg: epg received");
 				if (m_pCallBack!=NULL)
 				{
 					LogDebug("epg: do callback");
+
+					//	Notify manager we are finished
+					skyManager.OnEpgCallback();
+
 					m_pCallBack->OnEpgReceived();
 				}
 				m_bGrabbing=false;
 			}
-  	}
+
+			if(skyManager.HasEpgGrabbingAborted())
+			{
+				LogDebug("epg: Sky EPG grabbing aborted");
+				if (m_pCallBack!=NULL)
+				{
+					LogDebug("epg: do callback");
+					m_pCallBack->OnEpgReceived();
+				}
+				m_bGrabbing=false;
+			}
+		}
+		else
+		{
+			if(m_epgParser.IsEPGReady() && m_mhwParser.IsEPGReady())
+			{
+				LogDebug("epg: epg received");
+				if (m_pCallBack!=NULL)
+				{
+					LogDebug("epg: do callback");
+					m_pCallBack->OnEpgReceived();
+				}
+				m_bGrabbing=false;
+			}
+		}
+
+		
 	}
 	catch(...)
 	{
Index: DirectShowFilters/TsWriter/source/EpgScanner.h
===================================================================
--- DirectShowFilters/TsWriter/source/EpgScanner.h	(revision 27484)
+++ DirectShowFilters/TsWriter/source/EpgScanner.h	(working copy)
@@ -21,6 +21,7 @@
 #pragma once
 #include "epgparser.h"
 #include "mhwparser.h"
+#include "SkyManager.h"
 #include "criticalsection.h"
 #include "entercriticalsection.h"
 #include "..\..\shared\TsHeader.h"
@@ -59,6 +60,16 @@
 	STDMETHOD(GetMHWChannel)(THIS_ UINT channelNr, UINT* channelId, UINT* networkId, UINT* transportId, char** channelName)PURE;
 	STDMETHOD(GetMHWSummary)(THIS_ ULONG programId, char** summary)PURE;
 	STDMETHOD(GetMHWTheme)(THIS_ UINT themeId, char** theme)PURE;
+
+	//	Sky Epg grabbing
+	STDMETHOD(ActivateSkyEpgGrabber)(THIS_ UINT activateCountryId)PURE;
+	STDMETHOD(IsSkyEpgGrabberActive)(THIS_ byte* active)PURE;
+	STDMETHOD(IsSkyEpgReady)(THIS_ byte* ready)PURE;
+	STDMETHOD(HasSkyEpgAborted)(THIS_ byte* aborted)PURE;
+	STDMETHOD(ResetSkyEpgRetrieval)()PURE;
+	STDMETHOD(GetNextSkyEpgChannel)(THIS_ unsigned char* atEnd, unsigned short* channelId, unsigned short* networkId, unsigned short* transportId, unsigned short* serviceId)PURE;
+	STDMETHOD(GetNextSkyEpgChannelEvent)(THIS_ unsigned char* atEnd, unsigned short* eventId, unsigned short* mjdStart, unsigned int* startTime, unsigned int* duration, unsigned char** title, unsigned char** summary, unsigned char** theme, unsigned short* seriesId, byte* seriesTermination)PURE;
+
 	STDMETHOD(Reset)(THIS_)PURE;
 	STDMETHOD(AbortGrabbing)(THIS_)PURE;
   
@@ -89,6 +100,16 @@
 	STDMETHODIMP GetMHWChannel(UINT channelNr, UINT* channelId, UINT* networkId, UINT* transportId, char** channelName);
 	STDMETHODIMP GetMHWSummary(ULONG programId, char** summary);
 	STDMETHODIMP GetMHWTheme(UINT themeId, char** theme);
+
+	//	Sky Epg grabbing
+	STDMETHODIMP ActivateSkyEpgGrabber(UINT activateCountryId);
+	STDMETHODIMP IsSkyEpgGrabberActive(byte* active);
+	STDMETHODIMP IsSkyEpgReady(byte* ready);
+	STDMETHODIMP HasSkyEpgAborted(byte* aborted);
+	STDMETHODIMP ResetSkyEpgRetrieval();
+	STDMETHODIMP GetNextSkyEpgChannel(unsigned char* atEnd, unsigned short* channelId, unsigned short* networkId, unsigned short* transportId, unsigned short* serviceId);
+	STDMETHODIMP GetNextSkyEpgChannelEvent(unsigned char* atEnd, unsigned short* eventId, unsigned short* mjdStart, unsigned int* startTime, unsigned int* duration, unsigned char** title, unsigned char** summary, unsigned char** theme, unsigned short* seriesId, byte* seriesTermination);
+
 	STDMETHODIMP Reset();
 	STDMETHODIMP AbortGrabbing();
 	STDMETHODIMP SetCallBack(IEpgCallback* callback);
@@ -97,11 +118,13 @@
 protected:
 	CEpgParser m_epgParser;
 	CMhwParser m_mhwParser;
+	CSkyManager skyManager;
   IEpgCallback* m_pCallBack;
 
   	bool IsEPG_PID(int pid);
 	bool IsMHW_PID(int pid);
 	bool IsEIT_PID(int pid);
+	bool IsSkyEpg_PID(int pid);
 private:
 	bool m_bGrabbing;
 	CCriticalSection m_section;
Index: DirectShowFilters/TsWriter/source/HuffmanBranchNode.cpp
===================================================================
--- DirectShowFilters/TsWriter/source/HuffmanBranchNode.cpp	(revision 0)
+++ DirectShowFilters/TsWriter/source/HuffmanBranchNode.cpp	(revision 0)
@@ -0,0 +1,134 @@
+/* 
+ *	Copyright (C) 2006-2008 Team MediaPortal
+ *	http://www.team-mediaportal.com
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+
+#include "HuffmanNode.h";
+#include "HuffmanBranchNode.h"
+
+
+//	External logging method
+extern void LogDebug(const char *fmt, ...) ;
+
+//	Cstr
+CHuffmanBranchNode::CHuffmanBranchNode()
+{
+	left = NULL;
+	right = NULL;
+}
+
+//	Flzr
+CHuffmanBranchNode::~CHuffmanBranchNode()
+{
+	if(left != NULL)
+		delete left;
+
+	if(right != NULL)
+		delete right;
+
+	LogDebug("CHuffmanBranchNode::flzr()");
+}
+
+//	Gets the type of this node (branch node)
+int CHuffmanBranchNode::GetType()
+{
+	return HUFFMAN_BRANCH_NODE;
+}
+
+//	Gets the left node
+CHuffmanNode* CHuffmanBranchNode::GetLeft()
+{
+	return left;
+}
+
+//	Sets the right node
+void CHuffmanBranchNode::SetLeft(CHuffmanNode* newLeft)
+{
+	left = newLeft;
+}
+
+//	Gets the right node
+CHuffmanNode* CHuffmanBranchNode::GetRight()
+{
+	return right;
+}
+
+//	Sets the right node
+void CHuffmanBranchNode::SetRight(CHuffmanNode* newRight)
+{
+	right = newRight;
+}
+
+//	Traverses the tree to decode the huffman data
+bool CHuffmanBranchNode::Decode(byte** currentInputByte, byte* currentInputBit, byte* endInputByte, byte** currentOutputByte, byte* endOutputByte, bool* hasFinished)
+{
+	byte testByte = **currentInputByte;
+
+	byte bitTest = 0x80 >> *currentInputBit;
+	
+	CHuffmanNode* nextNode;
+
+	//	If right (0)
+	if((testByte & bitTest) == bitTest)
+	{
+		nextNode = GetRight();
+	}
+
+	//	Else left (1)
+	else
+	{
+		nextNode = GetLeft();
+	}
+
+	if(nextNode == NULL)
+	{
+		LogDebug("CHuffmanBranchNode::Decode() - No branch to follow.  Huffman tree hasnt been initialized properly, or is incomplete");
+		*hasFinished = true;
+		return false;
+	}
+
+	//	Once we go past the end of the input buffer, we have finished
+	if(*currentInputByte >= endInputByte)
+	{
+		*hasFinished = true;
+		return true;
+	}
+
+	//	Move to the next bit
+	(*currentInputBit)++;
+	
+	if(*currentInputBit == 8)
+	{
+		*currentInputBit = 0;
+		(*currentInputByte)++;
+		
+	}
+
+	/*
+	//	Once we go past the end of the input buffer, we have finished
+	if(*currentInputByte > endInputByte)
+	{
+		*hasFinished = true;
+		return true;
+	}
+*/
+	//	Pass to the next node in the tree to decode
+	return nextNode->Decode(currentInputByte, currentInputBit, endInputByte, currentOutputByte, endOutputByte, hasFinished);
+}
Index: DirectShowFilters/TsWriter/source/HuffmanBranchNode.h
===================================================================
--- DirectShowFilters/TsWriter/source/HuffmanBranchNode.h	(revision 0)
+++ DirectShowFilters/TsWriter/source/HuffmanBranchNode.h	(revision 0)
@@ -0,0 +1,60 @@
+/* 
+ *	Copyright (C) 2006-2008 Team MediaPortal
+ *	http://www.team-mediaportal.com
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include <windows.h>
+
+
+
+
+class CHuffmanBranchNode
+	: public CHuffmanNode
+{
+public:
+
+	//	Cstr/Flzr
+	CHuffmanBranchNode();
+	~CHuffmanBranchNode();
+
+	//	Sets the left node
+	void SetLeft(CHuffmanNode* newLeft);
+
+	//	Sets the right node
+	void SetRight(CHuffmanNode* newRight);
+
+	//	Gets the left node
+	CHuffmanNode* GetLeft();
+
+	//	Gets the right node
+	CHuffmanNode* GetRight();
+
+	//	Gets the type of the node
+	int GetType();
+
+	//	Traverses the tree to decode the huffman data
+	bool Decode(byte** currentInputByte, byte* currentInputBit, byte* endInputByte, byte** currentOutputByte, byte* endOutputByte, bool* hasFinished);
+
+private:
+	
+	//	Left/Right tree pointer (left=0, right=1)
+	CHuffmanNode* left;
+	CHuffmanNode* right;
+
+};
Index: DirectShowFilters/TsWriter/source/HuffmanLeafNode.cpp
===================================================================
--- DirectShowFilters/TsWriter/source/HuffmanLeafNode.cpp	(revision 0)
+++ DirectShowFilters/TsWriter/source/HuffmanLeafNode.cpp	(revision 0)
@@ -0,0 +1,77 @@
+/* 
+ *	Copyright (C) 2006-2008 Team MediaPortal
+ *	http://www.team-mediaportal.com
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+
+#include "HuffmanNode.h"
+#include "HuffmanLeafNode.h"
+
+
+
+//	External logging method
+extern void LogDebug(const char *fmt, ...) ;
+
+
+//	Cstr
+CHuffmanLeafNode::CHuffmanLeafNode(char* leafDecodedString)
+{
+	decodedString = leafDecodedString;
+}
+
+//	Gets the type of this node (branch node)
+int CHuffmanLeafNode::GetType()
+{
+	return HUFFMAN_LEAF_NODE;
+}
+
+//	Traverses the tree to decode the huffman data
+bool CHuffmanLeafNode::Decode(byte** currentInputByte, byte* currentInputBit, byte* endInputByte, byte** currentOutputByte, byte* endOutputByte, bool* hasFinished)
+{
+	//	Check we have enough room left in the output buffer
+	int decodedStringLength = strlen(decodedString);
+	int outputBufferBytesLeft = endOutputByte - *currentOutputByte;
+
+	if(decodedStringLength > outputBufferBytesLeft)
+	{
+		LogDebug("CHuffmanLeafNode::Decode() - not enough bytes left in output buffer to hold decoded string");
+
+		//	Failed
+		return false;
+	}
+	/*
+	//	If we are now past the first bit in the last byte of the buffer, we have finished
+	if(*currentInputByte >= endInputByte)// || (*currentInputByte == endInputByte && *currentInputBit >= 1))
+	{
+		*hasFinished = true;
+		return true;
+	}
+*/
+	//LogDebug("Leaf: %s - next bit: %u %u", decodedString, *currentInputByte, *currentInputBit);
+
+	//	Copy the decoded string to the output buffer
+	memcpy(*currentOutputByte, decodedString, decodedStringLength);
+
+	//	Move the output buffer to the new end position
+	*currentOutputByte = *currentOutputByte + decodedStringLength;
+	
+	
+
+	return true;
+}
Index: DirectShowFilters/TsWriter/source/HuffmanLeafNode.h
===================================================================
--- DirectShowFilters/TsWriter/source/HuffmanLeafNode.h	(revision 0)
+++ DirectShowFilters/TsWriter/source/HuffmanLeafNode.h	(revision 0)
@@ -0,0 +1,45 @@
+/* 
+ *	Copyright (C) 2006-2008 Team MediaPortal
+ *	http://www.team-mediaportal.com
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+
+#include <windows.h>
+
+
+class CHuffmanLeafNode
+	: public CHuffmanNode
+{
+public:
+
+	//	Cstr
+	CHuffmanLeafNode(char* leafDecodedString);
+
+	//	Gets the type of the node
+	int GetType();
+
+	//	Traverses the tree to decode the huffman data
+	bool Decode(byte** currentInputByte, byte* currentInputBit, byte* endInputByte, byte** currentOutputByte, byte* endOutputByte, bool* hasFinished);
+
+private:
+	
+	char* decodedString;
+
+};
+
Index: DirectShowFilters/TsWriter/source/HuffmanNode.cpp
===================================================================
--- DirectShowFilters/TsWriter/source/HuffmanNode.cpp	(revision 0)
+++ DirectShowFilters/TsWriter/source/HuffmanNode.cpp	(revision 0)
@@ -0,0 +1,28 @@
+/* 
+ *	Copyright (C) 2006-2008 Team MediaPortal
+ *	http://www.team-mediaportal.com
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+
+#include "HuffmanNode.h"
+
+//	Cstr
+CHuffmanNode::CHuffmanNode()
+{
+}
Index: DirectShowFilters/TsWriter/source/HuffmanNode.h
===================================================================
--- DirectShowFilters/TsWriter/source/HuffmanNode.h	(revision 0)
+++ DirectShowFilters/TsWriter/source/HuffmanNode.h	(revision 0)
@@ -0,0 +1,47 @@
+/* 
+ *	Copyright (C) 2006-2008 Team MediaPortal
+ *	http://www.team-mediaportal.com
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+
+
+#include <windows.h>
+
+
+#define HUFFMAN_BRANCH_NODE 0x01
+#define HUFFMAN_LEAF_NODE	0x02
+
+
+class CHuffmanNode
+{
+public:
+
+	//	Cstr
+	CHuffmanNode();
+
+	//	Gets the type (either branch node or leaf node)
+	virtual int GetType() = 0;
+
+	//	Traverses the tree to decode the huffman data
+	virtual bool Decode(byte** currentInputByte, byte* currentInputBit, byte* endInputByte, byte** currentOutputByte, byte* endOutputByte, bool* hasFinished) = 0;
+
+private:
+	
+
+};
Index: DirectShowFilters/TsWriter/source/HuffmanTree.cpp
===================================================================
--- DirectShowFilters/TsWriter/source/HuffmanTree.cpp	(revision 0)
+++ DirectShowFilters/TsWriter/source/HuffmanTree.cpp	(revision 0)
@@ -0,0 +1,187 @@
+/* 
+ *	Copyright (C) 2006-2008 Team MediaPortal
+ *	http://www.team-mediaportal.com
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+
+
+#include "HuffmanTree.h"
+
+
+
+//	External logging method
+extern void LogDebug(const char *fmt, ...) ;
+
+// Constr
+CHuffmanTree::CHuffmanTree()
+{
+	trunkNode = NULL;
+}
+
+//	Dstr
+CHuffmanTree::~CHuffmanTree()
+{
+	if(trunkNode != NULL)
+		delete trunkNode;
+}
+
+//	Adds a leaf node decoded string with the specified path
+void CHuffmanTree::AddLeaf(int path, int bitLength, char* decodedString)
+{
+	//	Shift the bits to the left hand side
+	path = path << (32 - bitLength);
+	
+	if(trunkNode == NULL)
+		trunkNode = new CHuffmanBranchNode();
+
+	CHuffmanBranchNode* currentNode = (CHuffmanBranchNode*) trunkNode;
+
+	//	Loop through all the bits to build the tree path for this leaf
+	for(int i = 0; i < bitLength - 1; i++)
+	{		
+		CHuffmanBranchNode* connectingNode = NULL;
+
+		//	If next bit 0, branch left
+		if((path & 0x80000000) == 0x00000000)
+		{		
+			connectingNode = (CHuffmanBranchNode*)currentNode->GetLeft();
+
+			//	Create if doesnt exist
+			if(connectingNode == NULL)
+			{
+				connectingNode = new CHuffmanBranchNode();
+				currentNode->SetLeft(connectingNode);
+			}
+		}
+
+		//	If next bit 1, branch right
+		else
+		{
+			connectingNode = (CHuffmanBranchNode*)currentNode->GetRight();
+
+			//	Create if doesnt exist
+			if(connectingNode == NULL)
+			{
+				connectingNode = new CHuffmanBranchNode();
+				currentNode->SetRight(connectingNode);
+			}
+		}
+
+		//	Move to next bit
+		path = path << 1;
+
+		//	Move to the connecting node
+		currentNode = connectingNode;
+	}
+
+	//	Create the leaf node
+	CHuffmanLeafNode* newLeafNode = new CHuffmanLeafNode(decodedString);
+
+
+	//	Leaf on left
+	if((path & 0x80000000) == 0x00000000)
+	{
+		//	Verify the leaf is empty
+		if(currentNode->GetLeft() != NULL)
+		{
+			LogDebug("CHuffmanTree::AddLeaf() - Error building Huffman tree, leaf node not empty as expected");
+			return;
+		}
+
+		currentNode->SetLeft(newLeafNode);
+
+		//LogDebug("CHuffmanTree::AddLeaf() - Added leaf node for \"%s\" on left", decodedString);
+	}
+
+	//	Leaf on right
+	else
+	{
+		//	Verify the leaf is empty
+		if(currentNode->GetRight() != NULL)
+		{
+			LogDebug("CHuffmanTree::AddLeaf() - Error building Huffman tree, leaf node not empty as expected");
+			return;
+		}
+
+		currentNode->SetRight(newLeafNode);
+		
+		//LogDebug("CHuffmanTree::AddLeaf() - Added leaf node for \"%s\" on right", decodedString);
+	}
+}
+
+//	Decodes the input string using the huffman tree, returning the decoded length
+int CHuffmanTree::Decode(byte* inputBuffer, int inputLength, byte startBit, byte* outputBuffer, int outputLength)
+{
+	byte* currentInputByte = inputBuffer;
+	byte* currentInputBit = &startBit;
+	byte* endInputByte = inputBuffer + inputLength;
+
+	byte* currentOutputByte = outputBuffer;
+	byte* endOutputByte = outputBuffer + outputLength;
+
+	//	Allow for terminating byte
+	outputLength--;	
+
+	//	Safeguard to prevent a bug causing an infinite loop!
+	int i = 0;
+	int maxIterations = 8192;
+
+	//LogDebug("Input length: %u", inputLength);
+
+	try
+	{
+		bool hasFinished = false;
+
+		while(!hasFinished && i < maxIterations)
+		{
+			bool result = trunkNode->Decode(&currentInputByte, currentInputBit, endInputByte, &currentOutputByte, endOutputByte, &hasFinished);
+
+			if(!result)
+			{
+				//LogDebug("CHuffmanTree::Decode() - Error, failed to decode huffman encoded buffer");
+				*outputBuffer = 0;
+				return 0;
+			}
+
+			i++;
+		}
+
+		if(i >= 8192)
+		{
+			LogDebug("CHuffmanTree::Decode - Error parsing decoded buffer, max iterations exceeded");
+			*outputBuffer = 0;
+			return 0;
+		}
+	}
+	catch(...)
+	{
+		LogDebug("CHuffmanTree::Decode - Exception whilst decoding input buffer");
+		return 0;
+	}
+
+	//	Add a terminating character to the output buffer
+	*currentOutputByte = 0;
+
+	//LogDebug("CHuffmanTree::Decode - Item decoded successfully:");
+	//LogDebug(outputBuffer);
+
+	
+	//	Return the decoded output length
+	return currentOutputByte - outputBuffer;
+}
Index: DirectShowFilters/TsWriter/source/HuffmanTree.h
===================================================================
--- DirectShowFilters/TsWriter/source/HuffmanTree.h	(revision 0)
+++ DirectShowFilters/TsWriter/source/HuffmanTree.h	(revision 0)
@@ -0,0 +1,47 @@
+/* 
+ *	Copyright (C) 2006-2008 Team MediaPortal
+ *	http://www.team-mediaportal.com
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include <windows.h>
+#include "HuffmanNode.h"
+#include "HuffmanBranchNode.h"
+#include "HuffmanLeafNode.h"
+
+
+
+class CHuffmanTree
+{
+public:
+
+	//	Cstr/destr
+	CHuffmanTree();
+	~CHuffmanTree();
+
+	//	Adds a leaf node to the tree
+	void AddLeaf(int path, int length, char* decodedString);
+
+	//	Decodes the input string using the huffman tree, returning the decoded length
+	int Decode(byte* input, int inputLength, byte startBit, byte* output, int outputLength);
+
+private:
+
+	CHuffmanNode* trunkNode;
+
+};
Index: DirectShowFilters/TsWriter/source/MhwParser.cpp
===================================================================
--- DirectShowFilters/TsWriter/source/MhwParser.cpp	(revision 27484)
+++ DirectShowFilters/TsWriter/source/MhwParser.cpp	(working copy)
@@ -114,6 +114,10 @@
 	try
 	{
 		CEnterCriticalSection enter(m_section);
+
+		if(m_bDone)
+			return;
+
 //		LogDebug("mhw new section pid:%x tableid:%x %x %x len:%d",pid,tableId,sections.Data[4],sections.Data[5],sections.Data[6], sections.SectionLength);
 		if (!IsSectionWanted(pid,tableId)) return;
 
@@ -191,10 +195,14 @@
 bool	CMhwParser::IsEPGReady()
 {
 	CEnterCriticalSection enter(m_section);
+
+	if(m_bDone)
+		return true;
+
 	int passed=(int)(time(NULL)-m_TimeOutTimer);
   if (passed>=30)
   {
-    LogDebug("mhw grabber ended");
+    //LogDebug("mhw grabber ended");
 	  m_bDone=true;
 	  m_bGrabbing=false;
   }
Index: DirectShowFilters/TsWriter/source/SkyChannelDecoder.cpp
===================================================================
--- DirectShowFilters/TsWriter/source/SkyChannelDecoder.cpp	(revision 0)
+++ DirectShowFilters/TsWriter/source/SkyChannelDecoder.cpp	(revision 0)
@@ -0,0 +1,155 @@
+/* 
+ *	Copyright (C) 2006-2008 Team MediaPortal
+ *	http://www.team-mediaportal.com
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "SkyChannelDecoder.h"
+#include "SkyChannelParser.h"
+#include "SkyManager.h"
+
+
+typedef struct SkyBouquet;
+
+
+//	Cstr
+CSkyChannelDecoder::CSkyChannelDecoder(CSkyChannelParser* parentSkyChannelParser)
+{
+	skyChannelParser = parentSkyChannelParser;
+
+}
+
+//	Flzr
+CSkyChannelDecoder::~CSkyChannelDecoder()
+{
+}
+
+//	Fired when a new channel network data section is received
+void CSkyChannelDecoder::OnNetworkDataSectionReceived(unsigned short pid, CSection* dataSection)
+{
+	CSkyManager* skyManager = skyChannelParser->GetSkyManager();
+
+	Mediaportal::CEnterCriticalSection enter(skyManager->criticalSection);
+
+	//	If all bouquets are already fully populated, return
+	if(skyManager->AreAllBouquetsPopulated())
+		return;
+
+	//	Check this table carries channel data
+	if(!skyManager->DoesTidCarryChannelNetworkData(dataSection->table_id))
+		return;
+
+	byte* buffer = dataSection->Data;
+	
+	int bouquetId = (buffer[3] << 8) + buffer[4];
+	int bouquetDescriptorLength = ((buffer[8] & 0x0F ) << 8) + buffer[9];
+
+	SkyBouquet* skyBouquet = skyManager->GetBouquet(bouquetId);
+
+	if(skyBouquet == NULL)
+	{
+		skyManager->LogError("CSkyChannelDecoder::OnNetworkDataSectionReceived() - Error, failed to create new or retrieve existing Sky bouquet");
+		return;
+	}
+
+	//	If the bouquet is not initialized, this is the first time we have seen it
+	if(!skyBouquet->isInitialized)
+	{
+		//	Populate first section number seen
+		skyBouquet->firstReceivedSectionNumber = dataSection->section_number;
+		skyBouquet->isInitialized = true;
+	}
+
+	else
+	{
+		//	If all the channels are already populated for this bouquet, we can skip this packet
+		if(skyBouquet->isPopulated)
+			return;
+		
+		//	If we are back round to the first section we saw for this bouquet, it is now fully populated
+		if(dataSection->section_number == skyBouquet->firstReceivedSectionNumber)
+		{
+			skyBouquet->isPopulated = true;
+			skyManager->NotifyBouquetPopulated();
+
+			return;
+		}
+	}
+
+	int body = 10 + bouquetDescriptorLength;
+    int bouquetPayloadLength = ((buffer[body + 0] & 0x0F) << 8) + buffer[body + 1];
+	int endOfPacket = body + bouquetPayloadLength + 2;
+	int currentTransportGroup = body + 2;
+
+	//	Loop through all transport groups in this packet
+	while(currentTransportGroup < endOfPacket)
+	{
+		//	Extract transport id and network id
+		unsigned short int transportId = (buffer[currentTransportGroup + 0] << 8) + buffer[currentTransportGroup + 1];
+		unsigned short int networkId = (buffer[currentTransportGroup + 2] << 8) + buffer[currentTransportGroup + 3];
+
+		int transportGroupLength = ((buffer[currentTransportGroup + 4] & 0x0F) << 8) + buffer[currentTransportGroup + 5];
+		int currentTransportDescriptor = currentTransportGroup + 6;
+		int endOfTransportGroupDescriptors = currentTransportDescriptor + transportGroupLength;
+
+		while(currentTransportDescriptor < endOfTransportGroupDescriptors)
+		{
+			//	Descriptor type
+			byte descriptorType = buffer[currentTransportDescriptor];
+
+			int descriptorLength = buffer[currentTransportDescriptor + 1];
+			int currentServiceDescriptor = currentTransportDescriptor + 2;
+			int endOfServiceDescriptors = currentServiceDescriptor + descriptorLength - 2;
+
+			//	If the descriptor is channel information (0xB1)
+			if(descriptorType == 0xB1)
+			{
+				while(currentServiceDescriptor < endOfServiceDescriptors)
+				{
+					//	Extract service id and channel information
+					int serviceId = (buffer[currentServiceDescriptor + 2] << 8) + buffer[currentServiceDescriptor + 3];
+					int channelId = (buffer[currentServiceDescriptor + 5] << 8) + buffer[currentServiceDescriptor + 6];
+					int skyChannelNumber = (buffer[currentServiceDescriptor + 7] << 8) + buffer[currentServiceDescriptor + 8];
+					
+					SkyChannel* skyChannel = skyManager->GetChannel(channelId);
+
+					//	If the channel information has not been populated, do this now
+					if(!skyChannel->isPopulated)
+					{
+						skyChannel->networkId = networkId;
+						skyChannel->transportId = transportId;
+						skyChannel->serviceId = serviceId;
+						skyChannel->epgChannelNumber = skyChannelNumber;
+						skyChannel->isPopulated = true;
+					}
+				
+					currentServiceDescriptor += 9;
+				}
+			}
+
+			currentTransportDescriptor += descriptorLength + 2;
+		}
+
+		//	Move to the next transport stream
+		currentTransportGroup += transportGroupLength + 6;
+	}
+
+	
+
+	
+}
Index: DirectShowFilters/TsWriter/source/SkyChannelDecoder.h
===================================================================
--- DirectShowFilters/TsWriter/source/SkyChannelDecoder.h	(revision 0)
+++ DirectShowFilters/TsWriter/source/SkyChannelDecoder.h	(revision 0)
@@ -0,0 +1,47 @@
+/* 
+ *	Copyright (C) 2006-2008 Team MediaPortal
+ *	http://www.team-mediaportal.com
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include <windows.h>
+#include "..\..\shared\SectionDecoder.h"
+#include "CriticalSection.h"
+#include "EnterCriticalSection.h"
+
+
+class CSkyChannelParser;
+
+class CSkyChannelDecoder
+{
+public:
+
+	//	Cstr
+	CSkyChannelDecoder(CSkyChannelParser* parentSkyChannelParser);
+	~CSkyChannelDecoder();
+
+	//	Fired when a new channel network data section is received
+	void OnNetworkDataSectionReceived(unsigned short pid, CSection* dataSection);
+
+private:
+
+	CSkyChannelParser* skyChannelParser;
+
+
+};
Index: DirectShowFilters/TsWriter/source/SkyChannelParser.cpp
===================================================================
--- DirectShowFilters/TsWriter/source/SkyChannelParser.cpp	(revision 0)
+++ DirectShowFilters/TsWriter/source/SkyChannelParser.cpp	(revision 0)
@@ -0,0 +1,81 @@
+/* 
+ *	Copyright (C) 2006-2008 Team MediaPortal
+ *	http://www.team-mediaportal.com
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+
+#include "SkyChannelParser.h"
+#include "SkyManager.h"
+
+//	Cstr
+CSkyChannelParser::CSkyChannelParser(CSkyManager *parentSkyManager)
+{
+	skyManager = parentSkyManager;
+
+	//	Initialize child objects
+	skyChannelDecoder = new CSkyChannelDecoder(this);
+
+	//	Initialize the section decoders
+	channelNetworkDataSectionDecoder = new CSectionDecoder();
+
+	channelNetworkDataSectionDecoder->SetCallBack(this);
+	channelNetworkDataSectionDecoder->SetPid(PID_SKYUKIT_EPG_CHANNEL_INFORMATION);
+}
+
+//	Flzr
+CSkyChannelParser::~CSkyChannelParser()
+{
+}
+
+//	Gets the parent sky manager reference
+CSkyManager* CSkyChannelParser::GetSkyManager()
+{
+	return skyManager;
+}
+
+//	Fired when a ts packet is received
+void CSkyChannelParser::OnTsPacket(CTsHeader& header, byte* tsPacket)
+{
+	Mediaportal::CEnterCriticalSection enter(skyManager->criticalSection);
+
+	unsigned short pid = header.Pid;
+
+	//	If we are grabbing epg
+	if(skyManager->IsEpgGrabbingActive())
+	{
+		//	If channel network data
+		if(skyManager->DoesPidCarryChannelNetworkData(pid))
+			channelNetworkDataSectionDecoder->OnTsPacket(header, tsPacket);
+	}
+}
+
+//	Fired when a new section is received
+void CSkyChannelParser::OnNewSection(int pid, int tableId, CSection& section)
+{
+	Mediaportal::CEnterCriticalSection enter(skyManager->criticalSection);
+
+	//	If we are grabbing epg
+	if(skyManager->IsEpgGrabbingActive())
+	{
+		//	If channel network data
+		if(skyManager->DoesPidCarryChannelNetworkData(pid))
+			skyChannelDecoder->OnNetworkDataSectionReceived(pid, &section);
+	}
+}
+
Index: DirectShowFilters/TsWriter/source/SkyChannelParser.h
===================================================================
--- DirectShowFilters/TsWriter/source/SkyChannelParser.h	(revision 0)
+++ DirectShowFilters/TsWriter/source/SkyChannelParser.h	(revision 0)
@@ -0,0 +1,62 @@
+/* 
+ *	Copyright (C) 2006-2008 Team MediaPortal
+ *	http://www.team-mediaportal.com
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include <vector>
+#include <windows.h>
+#include "SkyChannelDecoder.h"
+#include "..\..\shared\SectionDecoder.h"
+#include "..\..\shared\iSectionCallback.h"
+#include "CriticalSection.h"
+#include "EnterCriticalSection.h"
+
+using namespace std;
+
+class CSkyManager;
+
+
+class CSkyChannelParser
+	: public ISectionCallback
+{
+public:
+
+	CSkyChannelParser(CSkyManager* parentSkyManager);
+	~CSkyChannelParser();
+
+	//	Gets the parent sky manager reference
+	CSkyManager* GetSkyManager();
+
+	//	Fired when a new ts packed is received
+	void OnTsPacket(CTsHeader& header, byte* tsPacket);
+
+	//	Fired when a new section is received
+	void OnNewSection(int pid, int tableId, CSection& section);
+
+private:
+
+	CSkyManager* skyManager;
+
+	//	Child objects
+	CSkyChannelDecoder* skyChannelDecoder;
+
+	CSectionDecoder* channelNetworkDataSectionDecoder;
+
+};
Index: DirectShowFilters/TsWriter/source/SkyEpgParser.cpp
===================================================================
--- DirectShowFilters/TsWriter/source/SkyEpgParser.cpp	(revision 0)
+++ DirectShowFilters/TsWriter/source/SkyEpgParser.cpp	(revision 0)
@@ -0,0 +1,139 @@
+/* 
+ *	Copyright (C) 2006-2008 Team MediaPortal
+ *	http://www.team-mediaportal.com
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "SkyEpgParser.h"
+#include "SkyManager.h"
+
+
+//	Cstr
+CSkyEpgParser::CSkyEpgParser(CSkyManager* parentSkyManager)
+{
+	Mediaportal::CEnterCriticalSection enter(parentSkyManager->criticalSection);
+
+	try
+	{
+		skyManager = parentSkyManager;
+
+		//	Create child objects
+		skyEpgTitleDecoder = new CSkyEpgTitleDecoder(this);
+		skyEpgSummaryDecoder = new CSkyEpgSummaryDecoder(this);
+
+		//	Initialize all title section decoders
+		for(unsigned short i = PID_SKYUKIT_EPG_TITLES_F; i <= PID_SKYUKIT_EPG_TITLES_T; i++)
+		{
+			CSectionDecoder* newTitleDecoder = new CSectionDecoder();
+
+			newTitleDecoder->SetCallBack(this);
+			newTitleDecoder->SetPid(i);
+			newTitleDecoder->EnableCrcCheck(true);
+
+			epgSectionDecoders.insert(pair<unsigned short, CSectionDecoder*>(i, newTitleDecoder));
+		}
+		
+		//	Initialize all normal summary section decoders
+		for(unsigned short i = PID_SKYUKIT_EPG_SUMMARIES_F; i <= PID_SKYUKIT_EPG_SUMMARIES_T; i++)
+		{
+			CSectionDecoder* newSummaryDecoder = new CSectionDecoder();
+
+			newSummaryDecoder->SetCallBack(this);
+			newSummaryDecoder->SetPid(i);
+			newSummaryDecoder->EnableCrcCheck(true);
+
+			epgSectionDecoders.insert(pair<unsigned short, CSectionDecoder*>(i, newSummaryDecoder));
+		}
+		
+
+	}
+	catch(...)
+	{
+		LogDebug("CSkyEpgParser::CSkyEpgParser() - Exception in constructor");
+	}
+}
+
+//	Flzr
+CSkyEpgParser::~CSkyEpgParser()
+{
+}
+
+//	Gets the parent sky manager reference
+CSkyManager* CSkyEpgParser::GetSkyManager()
+{
+	return skyManager;
+}
+
+//	Fired when a new ts packet is received
+void CSkyEpgParser::OnTsPacket(CTsHeader& header, byte* tsPacket)
+{
+	Mediaportal::CEnterCriticalSection enter(skyManager->criticalSection);
+
+	//	If epg grabbing is not active, skip
+	if(!skyManager->IsEpgGrabbingActive())
+		return;
+
+	unsigned short pid = header.Pid;
+
+	//	If this pid carries epg data
+	if(skyManager->DoesPidCarryEpgData(pid))
+	{
+		//	Try and find the section decoder for this pid
+		map<unsigned short, CSectionDecoder*>::iterator epgSectionDecodersIterator = epgSectionDecoders.find(pid);
+		
+		//	If we couldnt find the decoder for this pid
+		if(epgSectionDecodersIterator == epgSectionDecoders.end())
+		{
+			skyManager->LogError("CSkyEpgParser::OnTsPacket() - Unexpected pid in ts packet");
+			return;
+		}
+
+		//	Else pass the packet to the section decoder
+		epgSectionDecodersIterator->second->OnTsPacket(header, tsPacket);
+	}
+}
+
+//	Fired when a new section is received
+void CSkyEpgParser::OnNewSection(int pid, int tableId, CSection& section)
+{
+	Mediaportal::CEnterCriticalSection enter(skyManager->criticalSection);
+
+	//	If epg grabbing is not active, skip
+	if(!skyManager->IsEpgGrabbingActive())
+		return;
+
+	//	If this is a title data section
+	if(skyManager->DoesPidCarryEpgTitleData(pid))
+	{
+		//	Pass to the title decoder
+		skyEpgTitleDecoder->OnTitleSectionReceived(pid, &section);
+	}
+
+	//	Else if summary data section
+	else if(skyManager->DoesPidCarryEpgSummaryData(pid))
+	{
+		//	Pass to the summary decoder
+		skyEpgSummaryDecoder->OnSummarySectionReceived(pid, &section);
+	}
+	
+	else
+	{
+		skyManager->LogError("CSkyEpgParser::OnNewSection() - Unexpected pid received in section");
+		return;
+	}
+}
Index: DirectShowFilters/TsWriter/source/SkyEpgParser.h
===================================================================
--- DirectShowFilters/TsWriter/source/SkyEpgParser.h	(revision 0)
+++ DirectShowFilters/TsWriter/source/SkyEpgParser.h	(revision 0)
@@ -0,0 +1,67 @@
+/* 
+ *	Copyright (C) 2006-2008 Team MediaPortal
+ *	http://www.team-mediaportal.com
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include <vector>
+#include <map>
+#include <windows.h>
+#include "SkyEpgTitleDecoder.h"
+#include "SkyEpgSummaryDecoder.h"
+#include "..\..\shared\SectionDecoder.h"
+#include "..\..\shared\iSectionCallback.h"
+#include "CriticalSection.h"
+#include "EnterCriticalSection.h"
+
+using namespace std;
+
+
+class CSkyManager;
+
+
+class CSkyEpgParser
+	: public ISectionCallback
+{
+public:
+
+	//	Cstr/Dstr
+	CSkyEpgParser(CSkyManager* parentSkyManager);
+	~CSkyEpgParser();
+
+	//	Gets the parent sky manager reference
+	CSkyManager* GetSkyManager();
+
+	//	Fired when a new ts packed is received
+	void OnTsPacket(CTsHeader& header, byte* tsPacket);
+
+	//	Fired when a new section is received
+	void OnNewSection(int pid, int tableId, CSection& section);
+
+
+private:
+
+	//	Parent Sky manager
+	CSkyManager* skyManager;
+
+	CSkyEpgTitleDecoder* skyEpgTitleDecoder;
+	CSkyEpgSummaryDecoder* skyEpgSummaryDecoder;
+
+	map<unsigned short, CSectionDecoder*> epgSectionDecoders;
+};
Index: DirectShowFilters/TsWriter/source/SkyEpgSummaryDecoder.cpp
===================================================================
--- DirectShowFilters/TsWriter/source/SkyEpgSummaryDecoder.cpp	(revision 0)
+++ DirectShowFilters/TsWriter/source/SkyEpgSummaryDecoder.cpp	(revision 0)
@@ -0,0 +1,215 @@
+/* 
+ *	Copyright (C) 2006-2008 Team MediaPortal
+ *	http://www.team-mediaportal.com
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+
+#include "SkyEpgSummaryDecoder.h"
+#include "SkyEpgParser.h"
+#include "SkyManager.h"
+
+
+//	Cstr
+CSkyEpgSummaryDecoder::CSkyEpgSummaryDecoder(CSkyEpgParser *parentSkyEpgParser)
+{
+	skyEpgParser = parentSkyEpgParser;
+}
+
+//	Flzr
+CSkyEpgSummaryDecoder::~CSkyEpgSummaryDecoder()
+{
+}
+
+//	Fired when a summary section is received
+void CSkyEpgSummaryDecoder::OnSummarySectionReceived(unsigned short pid, CSection *section)
+{
+	CSkyManager* skyManager = skyEpgParser->GetSkyManager();
+	
+	Mediaportal::CEnterCriticalSection enter(skyManager->criticalSection);
+
+	//	If the summary data carousel is complete for this pid, we can discard the data as we already have it
+	if(skyManager->IsSummaryDataCarouselOnPidComplete(pid))
+		return;
+
+	//	Validate table id
+	if(!skyManager->DoesTidCarryEpgSummaryData(section->table_id))
+		return;
+
+	byte* buffer = section->Data;
+
+	//	Total length of summary data (2 less for this length field)
+	int totalLength = (((buffer[1] & 0x0F) << 8) + buffer[2]) - 2;
+	
+	//	If this section is a valid length (14 absolute minimum with 1 blank summary)
+	if(section->section_length < 14)
+		return;
+
+	//	Get the channel id that this section's summary data relates to
+	unsigned short channelId = (buffer[3] << 8) + buffer[4];
+	unsigned short mjdStartDate = (buffer[8] << 8) + buffer[9];
+	
+	//	Check channel id and start date are valid
+	if(channelId == 0 || mjdStartDate == 0)
+		return;
+
+	//	Always starts at 10th byte
+	int currentSummaryItem = 10;
+
+	int iterationCounter = 0;
+
+	//	Loop while we have more summary data
+	while(currentSummaryItem < totalLength)
+	{
+		if(iterationCounter > 512)
+		{
+			skyManager->LogError("CSkyEpgTitleDecoder::OnSummarySectionReceived() - Error, infinite loop detected.  Dropping packet.");
+			return;
+		}
+
+		iterationCounter++;
+
+		//	Extract event id, header type and body length
+		unsigned short eventId = (buffer[currentSummaryItem + 0] << 8) + buffer[currentSummaryItem + 1];
+		unsigned char headerType = (buffer[currentSummaryItem + 2] & 0xF0 ) >> 4;
+		unsigned short bodyLength = ((buffer[currentSummaryItem + 2] & 0x0F) << 8) + buffer[currentSummaryItem + 3];
+
+		//	Build the carousel lookup id
+		unsigned int carouselLookupId = (channelId << 16) + eventId;
+
+		//	Notify the parser that a title has been received
+		skyManager->OnSummaryReceived(pid, carouselLookupId);
+
+		//	If the summary carousel for this pid is now complete, we can return
+		if(skyManager->IsSummaryDataCarouselOnPidComplete(pid))
+			return;
+
+		//	Get the epg event we are to populate from the manager
+		SkyEpgEvent* epgEvent = skyManager->GetEpgEvent(channelId, eventId);
+
+		//	Check we have the event reference
+		if(epgEvent == NULL)
+		{
+			skyManager->LogError("CSkyEpgSummaryDecoder::OnSummarySectionReceived() - Error, failed to get event reference");
+			return;
+		}
+
+		int headerLength;
+
+		//	If this is an extended header (0xF) (7 bytes long)
+		if(headerType == 0xF)
+			headerLength = 7;
+
+		//	Else if normal header (0xB) (4 bytes long)
+		else if(headerType == 0xB)
+			headerLength = 4;
+
+		//	Else other unknown header (not worked them out yet, at least 4 more)
+		//	Think these are only used for box office and adult channels so not really important
+		else
+		{
+			//	Cannot parse the rest of this packet as we dont know the header lengths/format etc
+			return;
+		}
+
+		
+		//	If body length is less than 3, there is no summary data for this event, move to next
+		if(bodyLength < 3)
+		{
+			currentSummaryItem += (headerLength + bodyLength);
+			continue;
+		}
+
+
+		//	Move to the body of the summary
+		int currentSummaryItemBody = currentSummaryItem + headerLength;
+
+		//	Extract summary signature and huffman buffer length
+		unsigned short summaryDescriptor = buffer[currentSummaryItemBody + 0];
+		unsigned short encodedBufferLength = buffer[currentSummaryItemBody + 1];
+		
+		//	If normal summary item (0xB9)
+		if(summaryDescriptor == 0xB9)	
+		{
+			if(epgEvent->summary == NULL)
+			{
+				//	Decode the summary
+				epgEvent->summary = skyManager->DecodeHuffmanData(&buffer[currentSummaryItemBody + 2], encodedBufferLength);
+
+				//	If failed to decode
+				if(epgEvent->summary == NULL)
+				{
+					char* cannotDecodeBuffer = "(Cannot decode)";
+					int cannotDecodeBufferLength = strlen(cannotDecodeBuffer) + 1;
+					epgEvent->summary = (byte*) malloc(cannotDecodeBufferLength);
+
+					memcpy(epgEvent->summary, cannotDecodeBuffer, cannotDecodeBufferLength);
+				}
+
+				else
+					//	Notify the manager (for statistics)
+					skyManager->OnSummaryDecoded();
+			}
+		}
+
+		//	Else if (0xBB) - Unknown data item (special box office or adult?)
+		//	Seems very rare (1 in every 2000 or so), so not important really
+		else if(summaryDescriptor == 0xBB)
+		{
+			//	Skip
+		}
+
+		//	Else other unknown data item, there are a few others that are unknown
+		else
+		{
+			return;
+			//skyManager->LogError("CSkyEpgSummaryDecoder::OnSummarySectionReceived() - Error, unrecognised summary descriptor");
+		}
+
+		//	Is there any footer information?
+		int footerLength = bodyLength - encodedBufferLength - 2;
+
+		if(footerLength >= 4)
+		{
+			int footerPointer = currentSummaryItemBody + 2 + encodedBufferLength;
+
+			//	Get the descriptor
+			short footerDescriptor = buffer[footerPointer + 0];
+
+			//	If series id information (0xC1)
+			if(footerDescriptor == 0xC1)
+			{
+				epgEvent->seriesId = (buffer[footerPointer + 2] << 8) + (buffer[footerPointer + 3] << 0);
+			}			
+		}		
+
+		//	Move to next summary item
+		currentSummaryItem += (bodyLength + headerLength);
+	}
+
+	//	Check the packet was parsed correctly - seem to get a few of these.  
+	//	Seems to be some extra information tagged onto the end of some summary packets (1 in every 2000 or so)
+	//	Not worked this out - possibly box office information
+	if(currentSummaryItem != (totalLength + 1))
+	{
+		//skyManager->LogError("CSkyEpgSummaryDecoder::OnSummarySectionReceived() - Warning, summary packet was not parsed correctly - pointer not in expected place");
+		
+		return;
+	}
+
+}
Index: DirectShowFilters/TsWriter/source/SkyEpgSummaryDecoder.h
===================================================================
--- DirectShowFilters/TsWriter/source/SkyEpgSummaryDecoder.h	(revision 0)
+++ DirectShowFilters/TsWriter/source/SkyEpgSummaryDecoder.h	(revision 0)
@@ -0,0 +1,47 @@
+/* 
+ *	Copyright (C) 2006-2008 Team MediaPortal
+ *	http://www.team-mediaportal.com
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include <windows.h>
+#include "..\..\shared\SectionDecoder.h"
+#include "CriticalSection.h"
+#include "EnterCriticalSection.h"
+
+class CSkyEpgParser;
+
+
+class CSkyEpgSummaryDecoder
+{
+public:
+
+	//	Cstr/Flzr
+	CSkyEpgSummaryDecoder(CSkyEpgParser* parentSkyEpgParser);
+	~CSkyEpgSummaryDecoder();
+
+	//	Fired when a summary section is received
+	void OnSummarySectionReceived(unsigned short pid, CSection* section);
+
+private:
+
+	CSkyEpgParser* skyEpgParser;
+
+
+};
Index: DirectShowFilters/TsWriter/source/SkyEpgTitleDecoder.cpp
===================================================================
--- DirectShowFilters/TsWriter/source/SkyEpgTitleDecoder.cpp	(revision 0)
+++ DirectShowFilters/TsWriter/source/SkyEpgTitleDecoder.cpp	(revision 0)
@@ -0,0 +1,206 @@
+/* 
+ *	Copyright (C) 2006-2008 Team MediaPortal
+ *	http://www.team-mediaportal.com
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "SkyEpgTitleDecoder.h"
+#include "SkyEpgParser.h"
+#include "SkyManager.h"
+#include "SkyThemes.h"
+
+
+//	Cstr
+CSkyEpgTitleDecoder::CSkyEpgTitleDecoder(CSkyEpgParser *parentSkyEpgParser)
+{
+	skyEpgParser = parentSkyEpgParser;
+}
+
+//	Flzr
+CSkyEpgTitleDecoder::~CSkyEpgTitleDecoder()
+{
+}
+
+//	Fired when a title section is received
+void CSkyEpgTitleDecoder::OnTitleSectionReceived(unsigned short pid, CSection *section)
+{
+	CSkyManager* skyManager = skyEpgParser->GetSkyManager();
+	
+	Mediaportal::CEnterCriticalSection enter(skyManager->criticalSection);
+
+	//	If the title data carousel is complete for this pid, we can discard the data as we already have it
+	if(skyManager->IsTitleDataCarouselOnPidComplete(pid))
+		return;
+
+	//	Validate table id
+	if(!skyManager->DoesTidCarryEpgTitleData(section->table_id))
+		return;
+
+	byte* buffer = section->Data;
+
+	//	Total length of title data (2 less for this length field)
+	int totalLength = (((buffer[1] & 0x0F) << 8) + buffer[2]) - 2;
+	
+	//	If this section is a valid length (20 absolute minimum with 1 blank title)
+	if(section->section_length < 20)
+		return;
+
+	//	Get the channel id that this section's summary data relates to
+	unsigned short channelId = (buffer[3] << 8) + buffer[4];
+	unsigned short mjdStart = (buffer[8] << 8) + buffer[9];
+	
+	//	Check channel id and start date are valid
+	if(channelId == 0 || mjdStart == 0)
+		return;
+
+	//	Always starts at 10th byte
+	int currentTitleItem = 10;
+
+	int iterationCounter = 0;
+
+	//	Loop while we have more summary data
+	while(currentTitleItem < totalLength)
+	{
+		if(iterationCounter > 512)
+		{
+			skyManager->LogError("CSkyEpgTitleDecoder::OnTitleSectionReceived() - Error, infinite loop detected.  Dropping packet.");
+			return;
+		}
+
+		iterationCounter++;
+
+		//	Extract event id, header type and body length
+		unsigned short eventId = (buffer[currentTitleItem + 0] << 8) + buffer[currentTitleItem + 1];
+		unsigned char headerType = (buffer[currentTitleItem + 2] & 0xF0 ) >> 4;
+		unsigned short bodyLength = ((buffer[currentTitleItem + 2] & 0x0F) << 8) + buffer[currentTitleItem + 3];
+
+		//	Build the carousel lookup id
+		unsigned int carouselLookupId = (channelId << 16) + eventId;
+
+		//	Notify the manager that a title has been received
+		skyManager->OnTitleReceived(pid, carouselLookupId);
+
+		//	If the title carousel for this pid is now complete, we can return
+		if(skyManager->IsTitleDataCarouselOnPidComplete(pid))
+			return;
+
+		//	Get the epg event we are to populate from the manager
+		SkyEpgEvent* epgEvent = skyManager->GetEpgEvent(channelId, eventId);
+
+		//	Check we have the event reference
+		if(epgEvent == NULL)
+		{
+			skyManager->LogError("CSkyEpgTitleDecoder::OnTitleSectionReceived() - Error, failed to get event reference");
+			return;
+		}
+
+		//	Set the event id and mjd start 
+		epgEvent->mjdStart = mjdStart;
+		epgEvent->eventId = eventId;
+
+		int headerLength = 4;
+
+		//	Move to the body of the summary
+		int currentTitleItemBody = currentTitleItem + headerLength;
+
+		//	Extract title descriptor and huffman buffer length
+		unsigned short titleDescriptor = buffer[currentTitleItemBody + 0];
+		unsigned short encodedBufferLength = buffer[currentTitleItemBody + 1] - 7;
+		
+		//	If normal title item (0xB5)
+		if(titleDescriptor == 0xB5)	
+		{
+			//	Start time stamp (multiplied by 2: << 1) as 86400 seconds in a day and 2 bytes can only store 65535
+			//	10800 = 0600
+			//	21600 = 12 noon
+			epgEvent->startTime = ((buffer[currentTitleItemBody + 2] << 8) + buffer[currentTitleItemBody + 3]) << 1;
+
+			//	Duration (multiplied by 2: << 1) as 86400 seconds in a day and 2 bytes can only store 65535
+			//	1800 = 1 hour
+			//	900 = 30 mins
+			epgEvent->duration = ((buffer[currentTitleItemBody + 4] << 8) + buffer[currentTitleItemBody + 5]) << 1;
+
+			//	Get the theme id
+			byte themeId = buffer[currentTitleItemBody + 6];
+
+			//	Set the event theme depending on country
+			switch(skyManager->GetCurrentCountryId())
+			{
+			case SKY_COUNTRY_UK:
+
+				epgEvent->theme = (byte*)ukThemes[themeId];
+				break;
+
+			case SKY_COUNTRY_IT:
+
+				epgEvent->theme = (byte*)itThemes[themeId];
+				break;
+			}
+
+			//	Extract the series termination flag (well its actually a series continuation flag, but we'll invert it to be more concise)
+			epgEvent->seriesTermination = ((buffer[currentTitleItemBody + 8] & 0x40) >> 6) ^ 0x01;
+
+			//	If there is no title huffman data, move to next item
+			if(encodedBufferLength <= 0)
+			{
+				currentTitleItem += (headerLength + bodyLength);
+				continue;
+			}
+
+			//	If this title has not yet been decoded
+			if(epgEvent->title == NULL)
+			{
+				//	Decode the huffman buffer
+				epgEvent->title = skyManager->DecodeHuffmanData(&buffer[currentTitleItemBody + 9], encodedBufferLength);
+
+				//	If failed to decode
+				if(epgEvent->title == NULL)
+				{
+					char* cannotDecodeBuffer = "(Cannot decode)";
+					int cannotDecodeBufferLength = strlen(cannotDecodeBuffer) + 1;
+					epgEvent->title = (byte*) malloc(cannotDecodeBufferLength);
+
+					memcpy(epgEvent->title, cannotDecodeBuffer, cannotDecodeBufferLength);
+				}
+
+				else
+					//	Notify the manager (for statistics)
+					skyManager->OnTitleDecoded();
+			}
+
+		}
+
+		//	Else other unknown data item
+		else
+		{
+			return;
+			//skyManager->LogError("CSkyEpgTitleDecoder::OnTitleSectionReceived() - Error, unrecognised title descriptor");
+		}
+		
+		//	Move to next summary item
+		currentTitleItem += (bodyLength + headerLength);
+	}
+
+	//	Check the packet was parsed correctly
+	if(currentTitleItem != (totalLength + 1))
+	{
+		//skyManager->LogError("CSkyEpgSummaryDecoder::OnTitleSectionReceived - Warning, title packet was not parsed correctly - pointer not in expected place");
+		return;
+	}
+
+}
Index: DirectShowFilters/TsWriter/source/SkyEpgTitleDecoder.h
===================================================================
--- DirectShowFilters/TsWriter/source/SkyEpgTitleDecoder.h	(revision 0)
+++ DirectShowFilters/TsWriter/source/SkyEpgTitleDecoder.h	(revision 0)
@@ -0,0 +1,47 @@
+/* 
+ *	Copyright (C) 2006-2008 Team MediaPortal
+ *	http://www.team-mediaportal.com
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#include <windows.h>
+#include "..\..\shared\SectionDecoder.h"
+#include "CriticalSection.h"
+#include "EnterCriticalSection.h"
+
+
+class CSkyEpgParser;
+
+
+class CSkyEpgTitleDecoder
+{
+public:
+
+	//	Cstr/Flzr
+	CSkyEpgTitleDecoder(CSkyEpgParser* parentSkyEpgParser);
+	~CSkyEpgTitleDecoder();
+
+	//	Fired when a title section is received
+	void OnTitleSectionReceived(unsigned short pid, CSection* section);
+
+private:
+
+	CSkyEpgParser* skyEpgParser;
+
+};
Index: DirectShowFilters/TsWriter/source/SkyManager.cpp
===================================================================
--- DirectShowFilters/TsWriter/source/SkyManager.cpp	(revision 0)
+++ DirectShowFilters/TsWriter/source/SkyManager.cpp	(revision 0)
@@ -0,0 +1,1758 @@
+/* 
+ *	Copyright (C) 2006-2008 Team MediaPortal
+ *	http://www.team-mediaportal.com
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "SkyManager.h"
+
+
+//	Cstr
+CSkyManager::CSkyManager()
+{
+	try
+	{
+		Mediaportal::CEnterCriticalSection enter(criticalSection);
+
+		LogDebug("CSkyManager::cstr()");
+
+		isInitialized = false;
+		epgFirmwareHuffmanTreesPopulated = false;
+		epgGrabbingAbortedThroughTooManyErrors = false;
+		
+		numberErrorsLogged = 0;
+		numberBouquetsPopulated = 0;
+		numberFailedHuffmanDecodes = 0;
+
+		//	Initialize all firmware huffman trees
+		if(!InitializeEpgFirmwareHuffmanTrees())
+			return;
+
+		//	Initialize child objects
+		skyEpgParser = new CSkyEpgParser(this);
+		skyChannelParser = new CSkyChannelParser(this);
+
+	}
+	catch(...)
+	{
+		LogDebug("CSkyManager::cstr() - Exception whilst initializing");
+		return;
+	}
+	
+	isInitialized = true;
+	LogDebug("CSkyManager::cstr() - Sky manager initialized successfully");
+
+}
+
+//	Flzr
+CSkyManager::~CSkyManager()
+{
+	Mediaportal::CEnterCriticalSection enter(criticalSection);
+	
+	LogDebug("CSkyManager::flzr()");
+
+	Reset();
+
+	//	Cleanup
+	delete skyEpgParser;
+	delete skyChannelParser;
+
+	//	Cleanup huffman tables
+	map<unsigned short, CHuffmanTree*>::iterator huffmanIterator;
+
+	for(huffmanIterator = countryFirmwareHuffmanTrees.begin(); huffmanIterator != countryFirmwareHuffmanTrees.end(); huffmanIterator++)
+	{
+		CHuffmanTree* currentHuffmanTree = huffmanIterator->second;
+
+		delete currentHuffmanTree;
+	}
+}
+
+//	Logs an error a maximum number of times
+void CSkyManager::LogError(const char* message)
+{
+	if(numberErrorsLogged >= MAX_LOGGED_ERRORS)
+		return;
+
+	LogDebug(message);
+
+	numberErrorsLogged++;
+
+	//	If number of errors is exceeded, abort active operations
+	if(numberErrorsLogged == MAX_LOGGED_ERRORS)
+	{
+		LogDebug("CSkyManager - Aborting all current operations, too many errors");
+		epgGrabbingAbortedThroughTooManyErrors = true;
+	}
+}
+
+//	Initializes all the epg firmware huffman trees
+bool CSkyManager::InitializeEpgFirmwareHuffmanTrees()
+{
+	try
+	{
+		Mediaportal::CEnterCriticalSection enter(criticalSection);
+
+
+		LogDebug("CSkyManager::InitializeEpgFirmwareHuffmanTrees()");
+
+		//	Create Sky UK firmware huffman tree
+		CHuffmanTree* ukFirmwareHuffmanTree = new CHuffmanTree();
+
+		//	Add to the country lookup
+		countryFirmwareHuffmanTrees.insert(pair<unsigned char, CHuffmanTree*>(SKY_COUNTRY_UK, ukFirmwareHuffmanTree));
+
+
+		//	Add all leaf nodes
+		ukFirmwareHuffmanTree->AddLeaf(0x055C614C, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C614D, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C614E, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C614F, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6150, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6151, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6152, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6153, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6154, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000008, 7, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000077, 7, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6155, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6156, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6157, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6158, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6159, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C615A, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C615B, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C615C, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C615D, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C615E, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C615F, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6160, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6161, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6162, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6163, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6164, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6165, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6166, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6167, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6168, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6169, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000006, 3, "\x20");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000218, 11, "\x21");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C616A, 27, "\x22");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C616B, 27, "\x23");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000AB8D, 16, "\x24");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C616C, 27, "\x25");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000041D, 11, "\x26");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000082, 8, "\x27");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000745, 11, "\x28");
+		ukFirmwareHuffmanTree->AddLeaf(0x000002AC, 10, "\x29");
+		ukFirmwareHuffmanTree->AddLeaf(0x000008AE, 12, "\x2A");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C616D, 27, "\x2B");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000058, 7, "\x2C");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000008B, 8, "\x2D");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000076, 7, "\x2E");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000051E, 14, "\x2F");
+		ukFirmwareHuffmanTree->AddLeaf(0x000001D2, 9, "\x30");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000167, 9, "\x31");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000228, 10, "\x32");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000020F, 10, "\x33");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000050, 10, "\x34");
+		ukFirmwareHuffmanTree->AddLeaf(0x000003A8, 10, "\x35");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000229, 10, "\x36");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000222, 10, "\x37");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000456, 11, "\x38");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000010D, 10, "\x39");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000746, 11, "\x3A");
+		ukFirmwareHuffmanTree->AddLeaf(0x000000A2, 11, "\x3B");
+		ukFirmwareHuffmanTree->AddLeaf(0x00001D1F, 13, "\x3C");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C616E, 27, "\x3D");
+		ukFirmwareHuffmanTree->AddLeaf(0x00001D4C, 13, "\x3E");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000EA7, 12, "\x3F");
+		ukFirmwareHuffmanTree->AddLeaf(0x0002AE31, 18, "\x40");
+		ukFirmwareHuffmanTree->AddLeaf(0x000000E2, 8, "\x41");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000040, 8, "\x42");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000042, 8, "\x43");
+		ukFirmwareHuffmanTree->AddLeaf(0x000001C7, 9, "\x44");
+		ukFirmwareHuffmanTree->AddLeaf(0x000003A0, 10, "\x45");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000154, 9, "\x46");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000110, 9, "\x47");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000155, 9, "\x48");
+		ukFirmwareHuffmanTree->AddLeaf(0x000003A1, 10, "\x49");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000029, 9, "\x4A");
+		ukFirmwareHuffmanTree->AddLeaf(0x000003A7, 10, "\x4B");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000106, 9, "\x4C");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000089, 8, "\x4D");
+		ukFirmwareHuffmanTree->AddLeaf(0x000001D7, 9, "\x4E");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000082, 9, "\x4F");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000015, 8, "\x50");
+		ukFirmwareHuffmanTree->AddLeaf(0x00001157, 13, "\x51");
+		ukFirmwareHuffmanTree->AddLeaf(0x000001D6, 9, "\x52");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000009, 7, "\x53");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000000B, 7, "\x54");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000055D, 11, "\x55");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000755, 11, "\x56");
+		ukFirmwareHuffmanTree->AddLeaf(0x000000B2, 8, "\x57");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000E36F, 16, "\x58");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000055E, 11, "\x59");
+		ukFirmwareHuffmanTree->AddLeaf(0x00001D50, 13, "\x5A");
+		ukFirmwareHuffmanTree->AddLeaf(0x00015719, 17, "\x5B");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C616F, 27, "\x5C");
+		ukFirmwareHuffmanTree->AddLeaf(0x0001C6DC, 17, "\x5D");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6170, 27, "\x5E");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6171, 27, "\x5F");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000752, 11, "\x60");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000009, 4, "\x61");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000070, 7, "\x62");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000039, 6, "\x63");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000009, 5, "\x64");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000000F, 4, "\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000021, 6, "\x66");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000023, 6, "\x67");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000017, 5, "\x68");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000005, 4, "\x69");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000071A, 11, "\x6A");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000040, 7, "\x6B");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000014, 5, "\x6C");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000002B, 6, "\x6D");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000007, 4, "\x6E");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000003, 4, "\x6F");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000007, 6, "\x70");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000055B, 11, "\x71");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000002, 4, "\x72");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000000, 4, "\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000006, 4, "\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000002D, 6, "\x75");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000054, 7, "\x76");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000006, 6, "\x77");
+		ukFirmwareHuffmanTree->AddLeaf(0x000003AB, 10, "\x78");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000011, 6, "\x79");
+		ukFirmwareHuffmanTree->AddLeaf(0x000002CC, 10, "\x7A");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6172, 27, "\x7B");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6173, 27, "\x7C");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6174, 27, "\x7D");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6175, 27, "\x7E");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6176, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6177, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6178, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6179, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C617A, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C617B, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C617C, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C617D, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C617E, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C617F, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6180, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6181, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6182, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6183, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6184, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6185, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6186, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6187, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6188, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6189, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C618A, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C618B, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C618C, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C618D, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C618E, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C618F, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6190, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6191, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6192, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x0001C6DD, 17, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6193, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6194, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6195, 27, "");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6196, 27, "\xA0");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6197, 27, "\xA1");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6198, 27, "\xA2");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C6199, 27, "\xA3");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C619A, 27, "\xA4");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C619B, 27, "\xA5");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C619C, 27, "\xA6");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C619D, 27, "\xA7");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C619E, 27, "\xA8");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C619F, 27, "\xA9");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61A0, 27, "\xAA");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61A1, 27, "\xAB");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61A2, 27, "\xAC");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61A3, 27, "\xAD");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61A4, 27, "\xAE");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61A5, 27, "\xAF");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61A6, 27, "\xB0");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61A7, 27, "\xB1");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61A8, 27, "\xB2");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61A9, 27, "\xB3");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61AA, 27, "\xB4");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61AB, 27, "\xB5");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61AC, 27, "\xB6");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61AD, 27, "\xB7");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61AE, 27, "\xB8");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61AF, 27, "\xB9");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61B0, 27, "\xBA");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61B1, 27, "\xBB");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61B2, 27, "\xBC");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61B3, 27, "\xBD");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61B4, 27, "\xBE");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61B5, 27, "\xBF");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61B6, 27, "\xC0");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61B7, 27, "\xC1");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61B8, 27, "\xC2");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61B9, 27, "\xC3");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61BA, 27, "\xC4");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61BB, 27, "\xC5");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61BC, 27, "\xC6");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61BD, 27, "\xC7");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61BE, 27, "\xC8");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61BF, 27, "\xC9");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61C0, 27, "\xCA");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61C1, 27, "\xCB");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61C2, 27, "\xCC");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61C3, 27, "\xCD");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61C4, 27, "\xCE");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61C5, 27, "\xCF");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61C6, 27, "\xD0");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61C7, 27, "\xD1");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61C8, 27, "\xD2");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61C9, 27, "\xD3");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61CA, 27, "\xD4");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61CB, 27, "\xD5");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61CC, 27, "\xD6");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61CD, 27, "\xD7");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61CE, 27, "\xD8");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61CF, 27, "\xD9");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61D0, 27, "\xDA");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61D1, 27, "\xDB");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61D2, 27, "\xDC");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61D3, 27, "\xDD");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61D4, 27, "\xDE");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61D5, 27, "\xDF");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61D6, 27, "\xE0");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61D7, 27, "\xE1");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61D8, 27, "\xE2");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61D9, 27, "\xE3");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61DA, 27, "\xE4");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61DB, 27, "\xE5");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61DC, 27, "\xE6");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61DD, 27, "\xE7");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61DE, 27, "\xE8");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61DF, 27, "\xE9");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61E0, 27, "\xEA");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61E1, 27, "\xEB");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61E2, 27, "\xEC");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61E3, 27, "\xED");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61E4, 27, "\xEE");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61E5, 27, "\xEF");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61E6, 27, "\xF0");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61E7, 27, "\xF1");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61E8, 27, "\xF2");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61E9, 27, "\xF3");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61EA, 27, "\xF4");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61EB, 27, "\xF5");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61EC, 27, "\xF6");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61ED, 27, "\xF7");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61EE, 27, "\xF8");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61EF, 27, "\xF9");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61F0, 27, "\xFA");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61F1, 27, "\xFB");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61F2, 27, "\xFC");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61F3, 27, "\xFD");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61F4, 27, "\xFE");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61F5, 27, "\xFF");
+		ukFirmwareHuffmanTree->AddLeaf(0x00002AFE, 14, "\x28\x49\x6E\x63\x6C\x75\x64\x69\x6E\x67\x20");
+		ukFirmwareHuffmanTree->AddLeaf(0x00003A22, 14, "\x28\x4E\x65\x77\x20\x53\x65\x72\x69\x65\x73\x29");
+		ukFirmwareHuffmanTree->AddLeaf(0x00001D1D, 13, "\x28\x50\x61\x72\x74\x20");
+		ukFirmwareHuffmanTree->AddLeaf(0x000003A6, 10, "\x28\x52\x65\x70\x65\x61\x74\x29");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000087, 9, "\x28\x53\x74\x65\x72\x65\x6F\x29");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000083, 9, "\x28\x53\x74\x65\x72\x65\x6F\x29\x20\x28\x54\x65\x6C\x65\x74\x65\x78\x74\x29");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000038C, 10, "\x28\x54\x65\x6C\x65\x74\x65\x78\x74\x29");
+		ukFirmwareHuffmanTree->AddLeaf(0x000041CE, 15, "\x28\x57\x69\x64\x65\x73\x63\x72\x65\x65\x6E\x29");
+		ukFirmwareHuffmanTree->AddLeaf(0x000055C7, 15, "\x41\x63\x74\x69\x6F\x6E");
+		ukFirmwareHuffmanTree->AddLeaf(0x00002CDF, 14, "\x41\x64\x76\x65\x6E\x74\x75\x72\x65\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000864, 13, "\x41\x6D\x65\x72\x69\x63\x61");
+		ukFirmwareHuffmanTree->AddLeaf(0x00007537, 15, "\x41\x6E\x69\x6D\x61\x74\x65\x64");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000865, 13, "\x41\x75\x73\x74\x72\x61\x6C\x69\x61");
+		ukFirmwareHuffmanTree->AddLeaf(0x00003AA2, 14, "\x41\x77\x61\x79");
+		ukFirmwareHuffmanTree->AddLeaf(0x00002AFF, 14, "\x42\x42\x43");
+		ukFirmwareHuffmanTree->AddLeaf(0x000038D8, 14, "\x42\x61\x62\x79");
+		ukFirmwareHuffmanTree->AddLeaf(0x00003AA3, 14, "\x42\x65\x73\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x00002CD8, 14, "\x42\x69\x67");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000115F, 13, "\x42\x69\x6C\x6C");
+		ukFirmwareHuffmanTree->AddLeaf(0x00001150, 13, "\x42\x6C\x61\x63\x6B");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000166E, 13, "\x42\x6C\x75\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000146, 12, "\x42\x72\x65\x61\x6B\x66\x61\x73\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000157C, 13, "\x42\x72\x69\x74\x61\x69\x6E");
+		ukFirmwareHuffmanTree->AddLeaf(0x00001D1C, 13, "\x42\x72\x69\x74\x69\x73\x68");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000866, 13, "\x42\x75\x73\x69\x6E\x65\x73\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000157D, 13, "\x43\x61\x6C\x6C");
+		ukFirmwareHuffmanTree->AddLeaf(0x00002AE0, 14, "\x43\x61\x72\x74\x6F\x6F\x6E");
+		ukFirmwareHuffmanTree->AddLeaf(0x00002AE1, 14, "\x43\x68\x61\x6E\x6E\x65\x6C");
+		ukFirmwareHuffmanTree->AddLeaf(0x00003AA7, 14, "\x43\x68\x69\x6C\x64\x72\x65\x6E");
+		ukFirmwareHuffmanTree->AddLeaf(0x000038D9, 14, "\x43\x6C\x6F\x63\x6B");
+		ukFirmwareHuffmanTree->AddLeaf(0x00003A23, 14, "\x43\x6F\x6D\x65\x64\x79");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000754A, 15, "\x43\x6F\x6F\x6B");
+		ukFirmwareHuffmanTree->AddLeaf(0x00007536, 15, "\x43\x6F\x75\x6E\x74\x72\x79");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000AB4, 12, "\x44\x69\x72\x65\x63\x74\x65\x64\x20\x62\x79\x20");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000867, 13, "\x44\x72\x61\x6D\x61");
+		ukFirmwareHuffmanTree->AddLeaf(0x00001151, 13, "\x45\x61\x73\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x000041CF, 15, "\x45\x64\x75\x63\x61\x74\x69\x6F\x6E");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000051F, 14, "\x45\x6E\x67\x6C\x69\x73\x68");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000028E, 13, "\x45\x75\x72\x6F\x70\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x00002CD9, 14, "\x45\x78\x74\x72\x61");
+		ukFirmwareHuffmanTree->AddLeaf(0x00002AE2, 14, "\x46\x69\x6E\x61\x6C");
+		ukFirmwareHuffmanTree->AddLeaf(0x000071B4, 15, "\x46\x69\x6E\x61\x6E\x63\x69\x61\x6C");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000E37, 12, "\x46\x6F\x72");
+		ukFirmwareHuffmanTree->AddLeaf(0x00003A3D, 14, "\x46\x72\x65\x6E\x63\x68");
+		ukFirmwareHuffmanTree->AddLeaf(0x00001152, 13, "\x46\x72\x6F\x6D");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000157E, 13, "\x47\x65\x6F\x72\x67\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000111A, 13, "\x47\x65\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x00002236, 14, "\x47\x69\x72\x6C\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x00002237, 14, "\x47\x6F\x6C\x64\x65\x6E");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000754B, 15, "\x47\x6F\x6C\x66");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000156A, 13, "\x47\x6F\x6F\x64");
+		ukFirmwareHuffmanTree->AddLeaf(0x00003A24, 14, "\x47\x72\x65\x61\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000754C, 15, "\x48\x61\x6D\x70\x73\x68\x69\x72\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x00001153, 13, "\x48\x65\x61\x64\x6C\x69\x6E\x65\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x00003A9A, 14, "\x48\x65\x61\x72");
+		ukFirmwareHuffmanTree->AddLeaf(0x00001070, 13, "\x48\x69\x6C\x6C");
+		ukFirmwareHuffmanTree->AddLeaf(0x000071B5, 15, "\x48\x6F\x6C\x6C\x79\x77\x6F\x6F\x64");
+		ukFirmwareHuffmanTree->AddLeaf(0x00001154, 13, "\x48\x6F\x6D\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x00003A25, 14, "\x48\x6F\x75\x72");
+		ukFirmwareHuffmanTree->AddLeaf(0x00001072, 13, "\x48\x6F\x75\x73\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000156B, 13, "\x48\x6F\x77");
+		ukFirmwareHuffmanTree->AddLeaf(0x00003AA4, 14, "\x49\x54\x4E");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000754D, 15, "\x49\x6D\x70\x6F\x72\x74\x61\x6E\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000115E, 13, "\x49\x6E\x63\x6C\x75\x64\x69\x6E\x67");
+		ukFirmwareHuffmanTree->AddLeaf(0x00003A26, 14, "\x49\x6E\x74\x65\x72\x6E\x61\x74\x69\x6F\x6E\x61\x6C");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000447, 11, "\x4A\x6F\x68\x6E");
+		ukFirmwareHuffmanTree->AddLeaf(0x00003A27, 14, "\x4C\x61\x73\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x000020E6, 14, "\x4C\x61\x74\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x000022AC, 14, "\x4C\x65\x61\x72\x6E");
+		ukFirmwareHuffmanTree->AddLeaf(0x000022AD, 14, "\x4C\x69\x74\x74\x6C\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x00001D10, 13, "\x4C\x69\x76\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x00003A3C, 14, "\x4C\x6F\x6E\x64\x6F\x6E");
+		ukFirmwareHuffmanTree->AddLeaf(0x00002CDE, 14, "\x4C\x6F\x6F\x6B");
+		ukFirmwareHuffmanTree->AddLeaf(0x000071B6, 15, "\x4C\x75\x6E\x63\x68");
+		ukFirmwareHuffmanTree->AddLeaf(0x00001155, 13, "\x4D\x61\x6E");
+		ukFirmwareHuffmanTree->AddLeaf(0x00001071, 13, "\x4D\x61\x72\x6B");
+		ukFirmwareHuffmanTree->AddLeaf(0x00000AB9, 12, "\x4D\x65\x72\x69\x64\x69\x61\x6E");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000166D, 13, "\x4D\x69\x63\x68\x61\x65\x6C");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61F6, 27, "\x4D\x69\x6E\x75\x74\x65\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61F7, 27, "\x4D\x6F\x72\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61F8, 27, "\x4D\x6F\x72\x6E\x69\x6E\x67");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61F9, 27, "\x4D\x75\x72\x64\x65\x72");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61FA, 27, "\x4E\x61\x74\x69\x6F\x6E");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61FB, 27, "\x4E\x65\x69\x67\x68\x62\x6F\x75\x72\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61FC, 27, "\x4E\x65\x77");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61FD, 27, "\x4E\x65\x77\x73\x20\x26\x20\x57\x65\x61\x74\x68\x65\x72");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61FE, 27, "\x4E\x65\x77\x73\x20\x41\x6E\x64\x20\x57\x65\x61\x74\x68\x65\x72");
+		ukFirmwareHuffmanTree->AddLeaf(0x055C61FF, 27, "\x50\x61\x75\x6C");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3000, 26, "\x50\x6C\x75\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3001, 26, "\x50\x72\x61\x79\x65\x72");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3002, 26, "\x50\x72\x65\x73\x65\x6E\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3003, 26, "\x50\x72\x65\x73\x65\x6E\x74\x65\x64\x20\x62\x79");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3004, 26, "\x51\x75\x69\x7A");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3005, 26, "\x52\x65\x67\x69\x6F\x6E\x61\x6C");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3006, 26, "\x52\x65\x70\x72\x65\x73\x65\x6E\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3007, 26, "\x52\x65\x73\x6F\x75\x72\x63\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3008, 26, "\x52\x65\x76\x69\x65\x77");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3009, 26, "\x52\x69\x63\x68\x61\x72\x64");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE300A, 26, "\x53\x63\x68\x6F\x6F\x6C");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE300B, 26, "\x53\x65\x72\x69\x65\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE300C, 26, "\x53\x65\x72\x76\x69\x63\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE300D, 26, "\x53\x68\x6F\x77");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE300E, 26, "\x53\x6D\x69\x74\x68");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE300F, 26, "\x53\x6F\x75\x74\x68");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3010, 26, "\x53\x70\x6F\x72\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3011, 26, "\x53\x74\x61\x72");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3012, 26, "\x53\x74\x72\x65\x65\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3013, 26, "\x54\x56");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3014, 26, "\x54\x65\x61\x63\x68\x69\x6E\x67");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3015, 26, "\x54\x68\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3016, 26, "\x54\x6F\x64\x61\x79");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3017, 26, "\x54\x6F\x6E\x69\x67\x68\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3018, 26, "\x57\x65\x61\x74\x68\x65\x72");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3019, 26, "\x57\x65\x73\x74\x65\x72\x6E");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE301A, 26, "\x57\x65\x73\x74\x6D\x69\x6E\x73\x74\x65\x72");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE301B, 26, "\x57\x69\x6C\x6C\x69\x61\x6D");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE301C, 26, "\x57\x69\x74\x68");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE301D, 26, "\x57\x6F\x72\x6C\x64");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE301E, 26, "\x61\x62\x6F\x75\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE301F, 26, "\x61\x63\x74\x69\x6F\x6E\x2D\x70\x61\x63\x6B\x65\x64");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3020, 26, "\x61\x64\x76\x65\x6E\x74\x75\x72\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3021, 26, "\x61\x66\x74\x65\x72\x6E\x6F\x6F\x6E");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3022, 26, "\x61\x6C\x65\x72\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3023, 26, "\x61\x6C\x6C\x2D\x73\x74\x61\x72\x20\x63\x61\x73\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3024, 26, "\x61\x6E\x64");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3025, 26, "\x61\x6E\x79\x77\x68\x65\x72\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3026, 26, "\x61\x75\x64\x69\x65\x6E\x63\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3027, 26, "\x62\x61\x73\x65\x64");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3028, 26, "\x62\x6F\x6F\x6B");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3029, 26, "\x62\x75\x73\x69\x6E\x65\x73\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE302A, 26, "\x62\x75\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE302B, 26, "\x63\x65\x6C\x65\x62\x72\x69\x74\x79");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE302C, 26, "\x63\x68\x61\x6E\x63\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE302D, 26, "\x63\x68\x61\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE302E, 26, "\x63\x68\x69\x6C\x64");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE302F, 26, "\x63\x6C\x61\x73\x73\x69\x63");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3030, 26, "\x63\x6F\x6E\x73\x75\x6D\x65\x72");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3031, 26, "\x63\x6F\x6E\x74\x65\x73\x74\x61\x6E\x74\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3032, 26, "\x63\x6F\x6E\x74\x69\x6E\x75\x65\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3033, 26, "\x63\x6F\x6E\x74\x72\x6F\x76\x65\x72\x73\x69\x61\x6C");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3034, 26, "\x64\x65\x61\x6C\x65\x72");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3035, 26, "\x64\x65\x6C\x69\x76\x65\x72");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3036, 26, "\x64\x69\x73\x63\x75\x73\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3037, 26, "\x64\x6F\x63\x75\x6D\x65\x6E\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3038, 26, "\x64\x72\x61\x6D\x61");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3039, 26, "\x65\x64\x69\x74\x69\x6F\x6E");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE303A, 26, "\x65\x64\x75\x63\x61\x74\x69\x6F\x6E");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE303B, 26, "\x65\x76\x65\x6E\x74\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE303C, 26, "\x65\x76\x65\x72\x79");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE303D, 26, "\x65\x78\x63\x65\x6C\x6C\x65\x6E\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE303E, 26, "\x65\x79\x65\x64");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE303F, 26, "\x66\x61\x6D\x69\x6C\x79");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3040, 26, "\x66\x61\x6D\x6F\x75\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3041, 26, "\x66\x65\x61\x74\x75\x72");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3042, 26, "\x66\x69\x6C\x6D");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3043, 26, "\x66\x6F\x6F\x74\x62\x61\x6C\x6C");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3044, 26, "\x66\x6F\x72");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3045, 26, "\x66\x72\x6F\x6D");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3046, 26, "\x67\x65\x6E\x65\x72\x61\x6C\x20\x6B\x6E\x6F\x77\x6C\x65\x64\x67\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3047, 26, "\x67\x65\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3048, 26, "\x67\x75\x65\x73\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3049, 26, "\x67\x75\x65\x73\x74\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE304A, 26, "\x68\x61\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE304B, 26, "\x68\x61\x76\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE304C, 26, "\x68\x65\x61\x64\x6C\x69\x6E\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE304D, 26, "\x68\x65\x72");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE304E, 26, "\x68\x69\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE304F, 26, "\x68\x6F\x6D\x65\x20\x61\x6E\x64\x20\x61\x62\x72\x6F\x61\x64");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3050, 26, "\x68\x6F\x73\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3051, 26, "\x68\x6F\x77");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3052, 26, "\x69\x6E");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3053, 26, "\x69\x6E\x63\x6C\x75\x64\x69\x6E\x67");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3054, 26, "\x69\x6E\x74\x65\x72\x6E\x61\x74\x69\x6F\x6E\x61\x6C");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3055, 26, "\x69\x6E\x74\x65\x72\x76\x69\x65\x77");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3056, 26, "\x69\x6E\x74\x72\x6F\x64\x75\x63\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3057, 26, "\x69\x6E\x76\x65\x73\x74\x69\x67\x61\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3058, 26, "\x69\x6E\x76\x69\x74\x65\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3059, 26, "\x69\x73\x73\x75\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE305A, 26, "\x6B\x6E\x6F\x77\x6C\x65\x64\x67\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE305B, 26, "\x6C\x69\x66\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE305C, 26, "\x6C\x69\x76\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE305D, 26, "\x6C\x6F\x6F\x6B");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE305E, 26, "\x6D\x61\x67\x61\x7A\x69\x6E\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE305F, 26, "\x6D\x65\x65\x74\x73\x20");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3060, 26, "\x6D\x6F\x72\x6E\x69\x6E\x67");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3061, 26, "\x6D\x6F\x72\x6E\x69\x6E\x67\x20\x6D\x61\x67\x61\x7A\x69\x6E\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3062, 26, "\x6D\x75\x73\x69\x63");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3063, 26, "\x6E\x65\x61\x72");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3064, 26, "\x6E\x65\x74\x77\x6F\x72\x6B");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3065, 26, "\x6E\x65\x77");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3066, 26, "\x6E\x65\x77\x20\x73\x65\x72\x69\x65\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3067, 26, "\x6E\x69\x67\x68\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3068, 26, "\x6F\x66");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3069, 26, "\x6F\x6E");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE306A, 26, "\x6F\x6E\x69\x67\x68\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE306B, 26, "\x6F\x75\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE306C, 26, "\x6F\x76\x65\x72");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE306D, 26, "\x70\x61\x72\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE306E, 26, "\x70\x65\x6F\x70\x6C\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE306F, 26, "\x70\x68\x6F\x6E\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3070, 26, "\x70\x6F\x6C\x69");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3071, 26, "\x70\x6F\x6C\x69\x63\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3072, 26, "\x70\x6F\x6C\x69\x74\x69\x63\x61\x6C\x20\x63\x68\x61\x74\x20\x73\x68\x6F\x77");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3073, 26, "\x70\x6F\x70\x75\x6C\x61\x72");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3074, 26, "\x70\x72\x65\x73\x65\x6E\x74\x65\x64\x20\x62\x79\x20");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3075, 26, "\x70\x72\x6F\x67\x72\x61\x6D\x6D");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3076, 26, "\x71\x75\x69\x7A");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3077, 26, "\x72\x65\x63\x6F\x6E\x73\x74\x72\x75\x63\x74\x69\x6F\x6E");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3078, 26, "\x72\x65\x70\x6F\x72\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3079, 26, "\x72\x65\x76\x69\x65\x77");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE307A, 26, "\x73\x63\x68\x6F\x6F\x6C");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE307B, 26, "\x73\x65\x72\x69\x65\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE307C, 26, "\x73\x68\x6F\x72\x74\x20");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE307D, 26, "\x73\x68\x6F\x77");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE307E, 26, "\x73\x6F\x6D\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE307F, 26, "\x73\x74\x61\x72\x72\x69\x6E\x67");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3080, 26, "\x73\x74\x61\x72\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3081, 26, "\x73\x74\x6F\x72\x69\x65\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3082, 26, "\x73\x74\x6F\x72\x79");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3083, 26, "\x73\x74\x75\x64\x69\x6F");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3084, 26, "\x73\x75\x72\x70\x72\x69\x73\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3085, 26, "\x74\x65\x6C\x6C\x65\x72");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3086, 26, "\x74\x68\x61\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3087, 26, "\x74\x68\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3088, 26, "\x74\x68\x65\x69\x72");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3089, 26, "\x74\x68\x65\x6D");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE308A, 26, "\x74\x68\x65\x79");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE308B, 26, "\x74\x68\x69\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE308C, 26, "\x74\x68\x72\x6F\x75\x67\x68");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE308D, 26, "\x74\x6F");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE308E, 26, "\x74\x6F\x70");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE308F, 26, "\x74\x72\x61\x6E\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3090, 26, "\x75\x6E\x64\x65\x72");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3091, 26, "\x75\x70");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3092, 26, "\x76\x65\x72\x79");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3093, 26, "\x76\x69\x64\x65\x6F");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3094, 26, "\x76\x69\x65\x77");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3095, 26, "\x76\x69\x6E\x74\x61\x67\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3096, 26, "\x76\x69\x73\x69\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3097, 26, "\x77\x61\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3098, 26, "\x77\x61\x79");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE3099, 26, "\x77\x65\x65\x6B");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE309A, 26, "\x77\x65\x6C\x6C");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE309B, 26, "\x77\x68\x61\x74");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE309C, 26, "\x77\x68\x65\x6E");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE309D, 26, "\x77\x68\x69\x63\x68");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE309E, 26, "\x77\x68\x69\x6C\x65");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE309F, 26, "\x77\x68\x6F");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE30A0, 26, "\x77\x69\x6C\x6C");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE30A1, 26, "\x77\x69\x6E");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE30A2, 26, "\x77\x69\x74\x68");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE30A3, 26, "\x77\x6F\x72\x64\x73");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE30A4, 26, "\x77\x6F\x72\x6C\x64");
+		ukFirmwareHuffmanTree->AddLeaf(0x02AE30A5, 26, "\x77\x72\x69\x74\x74\x65\x6E");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000088C, 12, "\x79\x65\x61\x72");
+		ukFirmwareHuffmanTree->AddLeaf(0x0000059A, 11, "\x79\x6F\x75");
+
+
+
+		
+		//	Create Sky Italy firmware huffman tree
+		CHuffmanTree* italyFirmwareHuffmanTree = new CHuffmanTree();
+
+		//	Add to the country lookup
+		countryFirmwareHuffmanTrees.insert(pair<unsigned char, CHuffmanTree*>(SKY_COUNTRY_IT, italyFirmwareHuffmanTree));
+
+
+		//	Add all leaf nodes
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EAA, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EAB, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EAC, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EAD, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EAE, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EAF, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EB0, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EB1, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EB2, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EB3, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EB4, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EB5, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EB6, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000004E, 7, "\x09");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EB7, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EB8, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EB9, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EBA, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EBB, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EBC, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EBD, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EBE, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EBF, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EC0, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EC1, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EC2, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EC3, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EC4, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EC5, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EC6, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EC7, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EC8, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000001, 2, "\x20");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001C1D, 13, "\x21");
+		italyFirmwareHuffmanTree->AddLeaf(0x0001C423, 17, "\x22");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EC9, 29, "\x23");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1ECA, 29, "\x24");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1ECB, 29, "\x25");
+		italyFirmwareHuffmanTree->AddLeaf(0x00003885, 14, "\x26");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000004, 7, "\x27");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000016A, 13, "\x28");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000D3F, 12, "\x29");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1ECC, 29, "\x2A");
+		italyFirmwareHuffmanTree->AddLeaf(0x00016B1F, 21, "\x2B");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000030, 6, "\x2C");
+		italyFirmwareHuffmanTree->AddLeaf(0x000000B3, 8, "\x2D");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000026, 6, "\x2E");
+		italyFirmwareHuffmanTree->AddLeaf(0x00007109, 15, "\x2F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000093, 8, "\x30");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000120, 9, "\x31");
+		italyFirmwareHuffmanTree->AddLeaf(0x000003D9, 10, "\x32");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000038E, 10, "\x33");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000625, 11, "\x34");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000F74, 12, "\x35");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000B2F, 12, "\x36");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000D1E, 12, "\x37");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000068E, 11, "\x38");
+		italyFirmwareHuffmanTree->AddLeaf(0x000003D7, 10, "\x39");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000123, 9, "\x3A");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000043D, 11, "\x3B");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1ECD, 29, "\x3C");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1ECE, 29, "\x3D");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1ECF, 29, "\x3E");
+		italyFirmwareHuffmanTree->AddLeaf(0x000019B6, 13, "\x3F");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000E210, 16, "\x40");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000000A, 8, "\x41");
+		italyFirmwareHuffmanTree->AddLeaf(0x000001E9, 9, "\x42");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000094, 8, "\x43");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000010A, 9, "\x44");
+		italyFirmwareHuffmanTree->AddLeaf(0x000001C0, 9, "\x45");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000038C, 10, "\x46");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000012C, 9, "\x47");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000021F, 10, "\x48");
+		italyFirmwareHuffmanTree->AddLeaf(0x000003DF, 10, "\x49");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000316, 10, "\x4A");
+		italyFirmwareHuffmanTree->AddLeaf(0x000007A3, 11, "\x4B");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000007D, 9, "\x4C");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000010D, 9, "\x4D");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000010B, 9, "\x4E");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000032B, 10, "\x4F");
+		italyFirmwareHuffmanTree->AddLeaf(0x000001A0, 9, "\x50");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000058, 11, "\x51");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000194, 9, "\x52");
+		italyFirmwareHuffmanTree->AddLeaf(0x000000B4, 8, "\x53");
+		italyFirmwareHuffmanTree->AddLeaf(0x000001AC, 9, "\x54");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000D13, 12, "\x55");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000243, 10, "\x56");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000346, 10, "\x57");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001C59, 13, "\x58");
+		italyFirmwareHuffmanTree->AddLeaf(0x000018F3, 13, "\x59");
+		italyFirmwareHuffmanTree->AddLeaf(0x000018A6, 13, "\x5A");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1ED0, 29, "\x5B");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1ED1, 29, "\x5C");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1ED2, 29, "\x5D");
+		italyFirmwareHuffmanTree->AddLeaf(0x00005AC4, 19, "\x5E");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1ED3, 29, "\x5F");
+		italyFirmwareHuffmanTree->AddLeaf(0x000002D7, 14, "\x60");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000001F, 5, "\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x000000E1, 8, "\x62");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000039, 6, "\x63");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000058, 7, "\x64");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000000A, 4, "\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000001B, 7, "\x66");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000003, 6, "\x67");
+		italyFirmwareHuffmanTree->AddLeaf(0x000000B6, 8, "\x68");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000001, 4, "\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000D10, 12, "\x6A");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000018C, 9, "\x6B");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000079, 7, "\x6C");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000022, 6, "\x6D");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000017, 5, "\x6E");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000002, 4, "\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000023, 6, "\x70");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000389, 10, "\x71");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000001B, 5, "\x72");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000000, 5, "\x73");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000001D, 5, "\x74");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000000E, 6, "\x75");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000067, 7, "\x76");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000066, 9, "\x77");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000071E, 11, "\x78");
+		italyFirmwareHuffmanTree->AddLeaf(0x000001ED, 9, "\x79");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000001A, 7, "\x7A");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1ED4, 29, "\x7B");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1ED5, 29, "\x7C");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1ED6, 29, "\x7D");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1ED7, 29, "\x7E");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1ED8, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x00002D60, 18, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1ED9, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EDA, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EDB, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EDC, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EDD, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EDE, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EDF, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x0001C422, 17, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x00002D61, 18, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EE0, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EE1, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EE2, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EE3, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EE4, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EE5, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EE6, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EE7, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000B58E, 20, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EE8, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EE9, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EEA, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EEB, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x00005AC5, 19, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EEC, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EED, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EEE, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EEF, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EF0, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EF1, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EF2, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EF3, 29, "");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EF4, 29, "\xA0");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EF5, 29, "\xA1");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EF6, 29, "\xA2");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EF7, 29, "\xA3");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EF8, 29, "\xA4");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EF9, 29, "\xA5");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EFA, 29, "\xA6");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EFB, 29, "\xA7");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EFC, 29, "\xA8");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EFD, 29, "\xA9");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EFE, 29, "\xAA");
+		italyFirmwareHuffmanTree->AddLeaf(0x016B1EFF, 29, "\xAB");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F00, 28, "\xAC");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F01, 28, "\xAD");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F02, 28, "\xAE");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F03, 28, "\xAF");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F04, 28, "\xB0");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F05, 28, "\xB1");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F06, 28, "\xB2");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F07, 28, "\xB3");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F08, 28, "\xB4");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F09, 28, "\xB5");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F0A, 28, "\xB6");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000B59, 16, "\xB7");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F0B, 28, "\xB8");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F0C, 28, "\xB9");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F0D, 28, "\xBA");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F0E, 28, "\xBB");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F0F, 28, "\xBC");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F10, 28, "\xBD");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F11, 28, "\xBE");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F12, 28, "\xBF");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F13, 28, "\xC0");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F14, 28, "\xC1");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F15, 28, "\xC2");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F16, 28, "\xC3");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F17, 28, "\xC4");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F18, 28, "\xC5");
+		italyFirmwareHuffmanTree->AddLeaf(0x000005AD, 15, "\xC6");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F19, 28, "\xC7");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F1A, 28, "\xC8");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F1B, 28, "\xC9");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F1C, 28, "\xCA");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F1D, 28, "\xCB");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F1E, 28, "\xCC");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F1F, 28, "\xCD");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F20, 28, "\xCE");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F21, 28, "\xCF");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F22, 28, "\xD0");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F23, 28, "\xD1");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F24, 28, "\xD2");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F25, 28, "\xD3");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F26, 28, "\xD4");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F27, 28, "\xD5");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F28, 28, "\xD6");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F29, 28, "\xD7");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F2A, 28, "\xD8");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F2B, 28, "\xD9");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F2C, 28, "\xDA");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F2D, 28, "\xDB");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F2E, 28, "\xDC");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F2F, 28, "\xDD");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F30, 28, "\xDE");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F31, 28, "\xDF");
+		italyFirmwareHuffmanTree->AddLeaf(0x00005AC6, 19, "\xE0");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F32, 28, "\xE1");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F33, 28, "\xE2");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F34, 28, "\xE3");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F35, 28, "\xE4");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F36, 28, "\xE5");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F37, 28, "\xE6");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F38, 28, "\xE7");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F39, 28, "\xE8");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F3A, 28, "\xE9");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F3B, 28, "\xEA");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F3C, 28, "\xEB");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F3D, 28, "\xEC");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F3E, 28, "\xED");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F3F, 28, "\xEE");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F40, 28, "\xEF");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F41, 28, "\xF0");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F42, 28, "\xF1");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F43, 28, "\xF2");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F44, 28, "\xF3");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F45, 28, "\xF4");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F46, 28, "\xF5");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F47, 28, "\xF6");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F48, 28, "\xF7");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F49, 28, "\xF8");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F4A, 28, "\xF9");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F4B, 28, "\xFA");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F4C, 28, "\xFB");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F4D, 28, "\xFC");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F4E, 28, "\xFD");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F4F, 28, "\xFE");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F50, 28, "\xFF");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000878, 12, "\x28\x64\x75\x72");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000007C, 9, "\x32\x30\x30\x31");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000E35, 12, "\x32\x30\x30\x32");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000879, 12, "\x41\x64\x75\x6C\x74\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000337, 10, "\x41\x6C\x6C\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x000005AC, 11, "\x41\x6D\x65\x72\x69\x63\x61\x6E");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000CAB, 12, "\x41\x72\x67\x65\x6E\x74\x69\x6E\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000C41, 12, "\x41\x74\x74\x75\x61\x6C\x69\x74\x61\x27");
+		italyFirmwareHuffmanTree->AddLeaf(0x000004BF, 11, "\x42\x61\x74\x65\x6D\x61\x6E");
+		italyFirmwareHuffmanTree->AddLeaf(0x000018BB, 13, "\x42\x65\x63\x68\x69\x73");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001A78, 13, "\x43\x61\x6D\x70\x69\x6F\x6E\x61\x74\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001A1D, 13, "\x43\x61\x72\x6C\x6F\x73");
+		italyFirmwareHuffmanTree->AddLeaf(0x000007BB, 11, "\x43\x61\x72\x74\x6F\x6F\x6E");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000432, 11, "\x43\x6C\x75\x62");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000861, 12, "\x43\x6F\x6D\x6D\x65\x64\x69\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x000005AD, 11, "\x43\x6F\x6E");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000191F, 13, "\x44\x27\x41\x6C\x6F\x27");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000257, 10, "\x44\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001EA3, 13, "\x44\x61\x6C");
+		italyFirmwareHuffmanTree->AddLeaf(0x000004BE, 11, "\x44\x61\x6C\x6C\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000F79, 12, "\x44\x72\x61\x6D\x6D\x61\x74\x69\x63\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001A3E, 13, "\x44\x75\x72\x61\x6E\x74\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x000018E6, 13, "\x45\x63\x68\x65\x76\x65\x72\x72\x69\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x000018E7, 13, "\x45\x6D\x6D\x61\x6E\x75\x65\x6C\x6C\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001A22, 13, "\x45\x6E\x7A\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000005B, 11, "\x46\x61\x72\x65\x73");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001918, 13, "\x46\x69\x67\x6C\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000035A, 10, "\x46\x69\x6C\x6D");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000084C, 12, "\x46\x69\x6E\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000005C, 11, "\x46\x69\x75\x6D\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000431, 11, "\x46\x72\x61\x6E\x63\x69\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000C48, 12, "\x47\x69\x61\x6C\x6C\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x000018E8, 13, "\x47\x69\x6F\x76\x61\x6E\x6E\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x000004F0, 11, "\x48\x61\x72\x72\x6F\x6E");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001A24, 13, "\x49\x54\x56");
+		italyFirmwareHuffmanTree->AddLeaf(0x000000CE, 10, "\x49\x6C");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000025B, 10, "\x49\x6E");
+		italyFirmwareHuffmanTree->AddLeaf(0x000007A1, 11, "\x49\x6E\x66\x6F\x72\x6D\x61\x7A\x69\x6F\x6E\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000210, 10, "\x49\x6E\x74\x72\x61\x74\x74\x65\x6E\x69\x6D\x65\x6E\x74\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000711, 11, "\x49\x74\x61\x6C\x69\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x000018E9, 13, "\x4A\x61\x76\x69\x65\x72");
+		italyFirmwareHuffmanTree->AddLeaf(0x000004AB, 11, "\x4A\x65\x61\x6E");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001EE5, 13, "\x4A\x6F\x68\x6E");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000185, 11, "\x4B\x61\x73\x73\x6F\x76\x69\x74\x7A");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000005D, 11, "\x4C\x27\x61\x70\x70\x61\x73\x73\x69\x6F\x6E\x61\x6E\x74\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000256, 10, "\x4C\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000627, 11, "\x4C\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000034E, 10, "\x4D\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000872, 12, "\x4D\x61\x67\x61\x7A\x69\x6E\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x000018EA, 13, "\x4D\x61\x6D\x6D\x75\x63\x63\x61\x72\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000592, 11, "\x4D\x61\x6E\x68\x61\x74\x74\x61\x6E");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001C5E, 13, "\x4D\x61\x72\x63\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x000004F6, 11, "\x4D\x61\x72\x79");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000186, 11, "\x4D\x61\x74\x68\x69\x65\x75");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001A7B, 13, "\x4D\x69\x63\x68\x61\x65\x6C");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000C8B, 12, "\x4D\x6F\x6D\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000005E, 11, "\x4E\x61\x64\x69\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000D3E, 12, "\x4E\x65\x77\x73");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000B2E, 12, "\x4E\x6F\x74\x69\x7A\x69\x61\x72\x69\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000244, 10, "\x4F\x72\x61\x72\x69\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000596, 11, "\x50\x61\x74\x72\x69\x63\x6B");
+		italyFirmwareHuffmanTree->AddLeaf(0x000000B3, 12, "\x50\x61\x75\x6C");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000626, 11, "\x50\x65\x72");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001955, 13, "\x50\x65\x74\x65\x72");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001C69, 13, "\x50\x72\x6F\x67\x72\x61\x6D\x6D\x61\x7A\x69\x6F\x6E\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x000004F7, 11, "\x50\x73\x79\x63\x68\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000190, 9, "\x52\x65\x67\x69\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000187, 11, "\x52\x65\x6E\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x000018F5, 13, "\x52\x6F\x73\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001EE4, 13, "\x52\x75\x62\x72\x69\x63\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001911, 13, "\x53\x61\x6E\x64\x72\x65\x6C\x6C\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x000018EB, 13, "\x53\x65\x69\x67\x6E\x65\x72");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000306, 12, "\x53\x65\x72\x76\x69\x7A\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000908, 12, "\x53\x6E\x6F\x77");
+		italyFirmwareHuffmanTree->AddLeaf(0x000018F6, 13, "\x53\x6F\x72\x76\x69\x6E\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001ADA, 13, "\x53\x74\x65\x66\x61\x6E\x69\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000F44, 12, "\x53\x74\x72\x65\x61\x6D");
+		italyFirmwareHuffmanTree->AddLeaf(0x000005AF, 11, "\x53\x74\x72\x65\x65\x74");
+		italyFirmwareHuffmanTree->AddLeaf(0x000018EC, 13, "\x53\x74\x72\x65\x67\x68\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x000018BA, 13, "\x54\x52\x41\x4D\x41\x3A");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000C72, 12, "\x54\x65\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000345, 10, "\x55\x53\x41");
+		italyFirmwareHuffmanTree->AddLeaf(0x000007BD, 11, "\x55\x6E");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000B22, 12, "\x55\x6E\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x000018ED, 13, "\x56\x65\x72\x6F\x6E\x65\x73\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000189, 11, "\x56\x69\x6E\x63\x65\x6E\x74");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000621, 11, "\x57\x61\x6C\x6C");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000316, 12, "\x57\x6F\x72\x6C\x64");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000433, 11, "\x58\x58\x58");
+		italyFirmwareHuffmanTree->AddLeaf(0x000003D6, 10, "\x61\x64");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000184, 11, "\x61\x66\x66\x69\x64\x61\x72\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000025E, 10, "\x61\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000001E, 7, "\x61\x6C");
+		italyFirmwareHuffmanTree->AddLeaf(0x000006B7, 11, "\x61\x6C\x6C\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000F75, 12, "\x61\x6C\x6C\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000E2E, 12, "\x61\x6D\x69\x63\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x000004F1, 11, "\x61\x6D\x6D\x61\x7A\x7A\x61\x72\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x000003D5, 10, "\x61\x6E\x64");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001919, 13, "\x61\x6E\x66\x69\x74\x65\x61\x74\x72\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x000004AA, 11, "\x61\x6E\x6E\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000019A, 9, "\x61\x73");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001AD9, 13, "\x61\x74\x74\x72\x61\x76\x65\x72\x73\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x000000B4, 12, "\x61\x76\x65\x72");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001A23, 13, "\x62\x61\x6D\x62\x69\x6E\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001C58, 13, "\x62\x61\x6E\x64\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x000005A8, 11, "\x62\x65\x6C\x6C\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001912, 13, "\x62\x72\x61\x6E\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x000004F2, 11, "\x62\x72\x6F\x6B\x65\x72");
+		italyFirmwareHuffmanTree->AddLeaf(0x000000B2, 12, "\x62\x75\x73\x69\x6E\x65\x73\x73");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000B23, 12, "\x63\x61\x73\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000043A, 11, "\x63\x61\x73\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000005F, 11, "\x63\x61\x73\x73\x65\x6C");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000714, 11, "\x63\x65\x72\x63\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000092, 8, "\x63\x68\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000018F, 11, "\x63\x68\x69\x6C\x6F\x6D\x65\x74\x72\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000C45, 12, "\x63\x69\x74\x74\x61\x27");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000C5C, 12, "\x63\x6F\x6D\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x000019B1, 13, "\x63\x6F\x6D\x70\x61\x67\x6E\x69\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x000000D2, 8, "\x63\x6F\x6E");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001A3F, 13, "\x63\x6F\x6E\x71\x75\x69\x73\x74\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000C44, 12, "\x63\x6F\x6E\x74\x72\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001C7E, 13, "\x63\x72\x65\x64\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000033E, 12, "\x63\x75\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000871, 12, "\x63\x75\x6C\x74\x75\x72\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000317, 12, "\x63\x75\x72\x69\x6F\x73\x69\x74\x61\x27");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000032, 8, "\x64\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001A25, 13, "\x64\x61\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x000007B0, 11, "\x64\x61\x6C");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000969, 12, "\x64\x61\x6C\x6C\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F51, 28, "\x64\x65\x63\x69\x64\x47\x32\x36\x36\x20\x20\x3A\x20\x20\x64\x65\x64\x69\x63\x61\x74\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000C40, 12, "\x64\x65\x67\x6C\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x000000C6, 10, "\x64\x65\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x000001E2, 9, "\x64\x65\x6C");
+		italyFirmwareHuffmanTree->AddLeaf(0x000002CA, 10, "\x64\x65\x6C\x6C\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000638, 11, "\x64\x65\x6C\x6C\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001951, 13, "\x64\x65\x73\x74\x72\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001E8B, 13, "\x64\x65\x76\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000020, 6, "\x64\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000191A, 13, "\x64\x69\x61\x62\x6F\x6C\x69\x63\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x000019B0, 13, "\x64\x69\x63\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000090B, 12, "\x64\x69\x72\x65\x74\x74\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000180, 11, "\x64\x69\x73\x74\x61\x6E\x7A\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000593, 11, "\x64\x69\x76\x69\x64\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x000018EE, 13, "\x64\x69\x76\x69\x73\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001A79, 13, "\x64\x6F\x6C\x63\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001EA2, 13, "\x64\x6F\x6D\x61\x6E\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000031F, 10, "\x64\x75\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000018D, 9, "\x65\x27");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000016F, 9, "\x65\x64");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001C40, 13, "\x65\x73\x73\x65\x72\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001C7D, 13, "\x65\x73\x73\x65\x72\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x00B58F52, 28, "\x65\x76\x65\x6E\x74\x69\x47");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000033F, 12, "\x66\x61\x74\x74\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x000005A9, 11, "\x66\x65\x73\x74\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000423, 11, "\x66\x69\x6C\x6D");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001C43, 13, "\x67\x65\x6D\x65\x6C\x6C\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x000007A0, 11, "\x67\x69\x6F\x72\x6E\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000706, 11, "\x67\x69\x6F\x76\x61\x6E\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001EF1, 13, "\x67\x69\x6F\x76\x61\x6E\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000012E, 9, "\x67\x6C\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001C5F, 13, "\x67\x72\x61\x6E\x64\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001E8A, 13, "\x67\x72\x61\x6E\x64\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000191B, 13, "\x67\x72\x69\x67\x69\x27");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000315, 10, "\x68\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x000000CB, 8, "\x69\x6C");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000191C, 13, "\x69\x6D\x62\x61\x74\x74\x65\x72\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000006A, 7, "\x69\x6E");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001950, 13, "\x69\x6E\x63\x69\x6E\x74\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000C49, 12, "\x69\x6E\x66\x6F\x72\x6D\x61\x7A\x69\x6F\x6E\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000254, 10, "\x69\x6E\x69\x7A\x69\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000877, 12, "\x69\x6E\x74\x65\x72\x6E\x61\x7A\x69\x6F\x6E\x61\x6C\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000909, 12, "\x69\x6E\x74\x65\x72\x76\x69\x73\x74\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x000000CC, 8, "\x6C\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000686, 11, "\x6C\x61\x76\x6F\x72\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x000000D7, 8, "\x6C\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x000018EF, 13, "\x6C\x65\x76\x61\x74\x72\x69\x63\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x000018F4, 13, "\x6C\x69\x62\x72\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x000001E3, 9, "\x6C\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000628, 11, "\x6C\x6F\x72\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000009F, 8, "\x6D\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000876, 12, "\x6D\x61\x67\x67\x69\x6F\x72\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000590, 11, "\x6D\x61\x6C\x63\x61\x70\x69\x74\x61\x74\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x000018F0, 13, "\x6D\x61\x73\x63\x68\x69\x65\x74\x74\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000715, 11, "\x6D\x6F\x6E\x64\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000E0F, 12, "\x6D\x75\x73\x69\x63\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000F73, 12, "\x6E\x61\x74\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x000007B8, 11, "\x6E\x65\x6C");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001EA0, 13, "\x6E\x65\x6C\x6C\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000424, 11, "\x6E\x65\x6C\x6C\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x000004B5, 11, "\x6E\x65\x77\x73");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000019E, 11, "\x6E\x6F\x6E");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000191D, 13, "\x6E\x6F\x72\x64");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000307, 12, "\x6E\x75\x6F\x76\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x000002D5, 10, "\x6F\x66");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000873, 12, "\x6F\x67\x6E\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000342, 10, "\x6F\x72\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001ADB, 13, "\x70\x61\x72\x74\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000003F, 8, "\x70\x65\x72");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001A7A, 13, "\x70\x69\x63\x63\x6F\x6C\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000027A, 10, "\x70\x69\x75\x27");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000018E, 11, "\x70\x6F\x6C\x69\x7A\x69\x6F\x74\x74\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000181, 11, "\x70\x6F\x72\x70\x6F\x72\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001C7C, 13, "\x70\x72\x69\x6D\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x000018F7, 13, "\x70\x72\x6F\x64\x75\x74\x74\x6F\x72\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001C68, 13, "\x70\x72\x6F\x67\x72\x61\x6D\x6D\x61\x7A\x69\x6F\x6E\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001AD8, 13, "\x70\x72\x6F\x70\x72\x69\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000245, 10, "\x70\x72\x6F\x73\x73\x69\x6D\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001EC6, 13, "\x71\x75\x61\x74\x74\x72\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x000018F1, 13, "\x72\x65\x67\x69\x6D\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x000005AE, 11, "\x72\x69\x63\x63\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001954, 13, "\x72\x69\x63\x6F\x72\x64\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001C41, 13, "\x72\x6F\x76\x69\x6E\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001C1C, 13, "\x73\x61\x6C\x76\x61\x72\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x000019B7, 13, "\x73\x63\x72\x69\x74\x74\x6F\x72\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001A1E, 13, "\x73\x63\x72\x69\x76\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001EC7, 13, "\x73\x65\x72\x69\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000870, 12, "\x73\x65\x72\x76\x69\x7A\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x000018A7, 13, "\x73\x65\x74\x74\x69\x6D\x61\x6E\x61\x6C\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x000000F0, 8, "\x73\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000188, 11, "\x73\x69\x6E\x67\x6F\x6C\x61\x72\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000C8A, 12, "\x73\x6F\x6C\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000623, 11, "\x73\x6F\x6E\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000422, 11, "\x73\x74\x65\x73\x73\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000071B, 11, "\x73\x74\x6F\x72\x69\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001910, 13, "\x73\x74\x72\x65\x67\x68\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000382, 10, "\x73\x75");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000425, 11, "\x73\x75\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000968, 12, "\x73\x75\x63\x63\x65\x73\x73\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000CD9, 12, "\x73\x75\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000090A, 12, "\x73\x75\x6C\x6C\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000427, 11, "\x73\x75\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001A1C, 13, "\x73\x75\x6F\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000CA9, 12, "\x74\x61\x6C\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000F62, 12, "\x74\x65\x6D\x70\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x000007A9, 11, "\x74\x68\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000191E, 13, "\x74\x69\x6D\x69\x64\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x000004F3, 11, "\x74\x6F\x72\x74\x75\x72\x61\x72\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x000001A6, 9, "\x74\x72\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x000018F2, 13, "\x74\x72\x61\x73\x66\x6F\x72\x6D\x61\x72\x6C\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000182, 11, "\x74\x72\x65\x63\x65\x6E\x74\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001A1F, 13, "\x74\x72\x6F\x76\x61\x74\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000CDA, 12, "\x74\x75\x74\x74\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001913, 13, "\x75\x6C\x74\x69\x6D\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x000000C9, 8, "\x75\x6E");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000016E, 9, "\x75\x6E\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000E2D, 12, "\x75\x6E\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001EF0, 13, "\x75\x6F\x6D\x69\x6E\x69");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000018A, 11, "\x76\x65\x64\x6F\x6E\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000084D, 12, "\x76\x65\x6E\x67\x6F\x6E\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000860, 12, "\x76\x65\x72\x73\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00000C52, 12, "\x76\x69\x61\x67\x67\x69\x6F");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001EA1, 13, "\x76\x69\x65\x6E\x65");
+		italyFirmwareHuffmanTree->AddLeaf(0x0000062F, 11, "\x76\x69\x74\x61");
+		italyFirmwareHuffmanTree->AddLeaf(0x00001C7F, 13, "\x76\x75\x6F\x6C\x65");
+
+	}
+	catch(...)
+	{
+		LogDebug("CSkyManager::InitializeEpgFirmwareHuffmanTrees() - Exception whilst initializing firmware huffman trees");
+		return false;
+	}
+
+	LogDebug("CSkyManager::InitializeEpgFirmwareHuffmanTrees() - Firmware huffman trees populated successfully");
+
+	return true;
+}
+
+//	Resets the manager
+void CSkyManager::Reset()
+{
+	Mediaportal::CEnterCriticalSection enter(criticalSection);
+
+	//	TODO - free previous grab
+
+	//	We need to free the memory used by the previous grab
+	map<unsigned short, SkyChannel*>::iterator channelsIt;
+
+	//	Loop through all channels
+	for(channelsIt = channels.begin(); channelsIt != channels.end(); channelsIt++)
+	{
+		SkyChannel* currentChannel = channelsIt->second;
+
+		//	If this channel has events
+		if(currentChannel->events != NULL)
+		{
+			map<unsigned short, SkyEpgEvent*>::iterator epgEventsIt;
+
+			//	Loop through all events to clear them
+			for(epgEventsIt = currentChannel->events->begin(); epgEventsIt != currentChannel->events->end(); epgEventsIt++)
+			{
+				SkyEpgEvent* skyEpgEvent = epgEventsIt->second;
+
+				//	Clear titles and summaries if used
+				if(skyEpgEvent->title != NULL)
+					free(skyEpgEvent->title);
+
+				if(skyEpgEvent->summary != NULL)
+					free(skyEpgEvent->summary);
+
+				delete skyEpgEvent;
+			}
+
+			//	Clear the events map
+			currentChannel->events->clear();
+
+			delete currentChannel->events;
+		}
+
+		//	Delete the channel
+		delete currentChannel;
+	}
+
+	channels.clear();
+
+	//	Free all bouquets
+	map<unsigned short, SkyBouquet*>::iterator bouquetsIt;
+
+	for(bouquetsIt = bouquets.begin(); bouquetsIt != bouquets.end(); bouquetsIt++)
+	{
+		delete bouquetsIt->second;
+	}
+
+	bouquets.clear();
+
+	//	Reset the number of titles/summaries decoded
+	titlesDecoded = 0;
+	summariesDecoded = 0;
+
+	//	Clear carousel lookups
+	titleDataCarouselStartLookup.clear();
+	completedTitleDataCarousels.clear();
+	summaryDataCarouselStartLookup.clear();
+	completedSummaryDataCarousels.clear();
+
+	numberErrorsLogged = 0;
+	numberBouquetsPopulated = 0;
+	numberFailedHuffmanDecodes = 0;
+
+	isEpgGrabbingActive = false;
+	epgGrabbingAbortedThroughTooManyErrors = false;
+	
+	LogDebug("CSkyManager::Reset() - Reset successful");
+}
+
+//	Activates the EPG grabber for the specified country code
+void CSkyManager::ActivateEpgGrabber(unsigned short activateCountryId)
+{
+	Mediaportal::CEnterCriticalSection enter(criticalSection);
+
+	currentCountryId = activateCountryId;
+
+	if(currentCountryId == SKY_COUNTRY_UK)
+	{
+		LogDebug("CSkyManager::ActivateEpgGrabber() - Activated Sky EPG grabber for country: UK");
+		isEpgGrabbingActive = true;
+	}
+
+	else if(currentCountryId == SKY_COUNTRY_IT)
+	{
+		LogDebug("CSkyManager::ActivateEpgGrabber() - Activated Sky EPG grabber for country: Italy");
+		isEpgGrabbingActive = true;
+	}
+
+	else
+	{
+		LogDebug("CSkyManager::ActivateEpgGrabber() - Error, invalid country id specified");
+		isEpgGrabbingActive = false;
+	}
+	
+	numberBouquetsPopulated = 0;
+}
+
+//	De-activates the epg grabber
+void CSkyManager::DeActivateEpgGrabber()
+{
+	Mediaportal::CEnterCriticalSection enter(criticalSection);
+	
+	LogDebug("CSkyManager::DeActivateEpgGrabber()");
+
+	isEpgGrabbingActive = false;
+}
+
+//	Is the epg grabber active
+bool CSkyManager::IsEpgGrabbingActive()
+{
+	return isEpgGrabbingActive;
+}
+
+//	Has the epg grabber finished
+bool CSkyManager::IsEpgGrabbingFinished()
+{
+	return AreAllBouquetsPopulated() && AreAllTitlesPopulated() && AreAllSummariesPopulated();
+}
+//	Has the EPG grabbing been aborted through too many errors?
+bool CSkyManager::HasEpgGrabbingAborted()
+{
+	return epgGrabbingAbortedThroughTooManyErrors;
+}
+//	Fired when a new ts packet is received
+void CSkyManager::OnTsPacket(CTsHeader& header, byte* tsPacket)
+{
+	unsigned short pid = header.Pid;
+
+	//	If we are grabbing epg, pass the packet to the relavent parser
+	if(isEpgGrabbingActive)
+	{
+		if(DoesPidCarryChannelNetworkData(pid))
+			skyChannelParser->OnTsPacket(header, tsPacket);
+
+		else if(DoesPidCarryEpgData(pid))
+			skyEpgParser->OnTsPacket(header, tsPacket);
+	}
+}
+
+//	Does this pid carry channel network data?
+bool CSkyManager::DoesPidCarryChannelNetworkData(int pid)
+{
+	return pid == PID_SKYUKIT_EPG_CHANNEL_INFORMATION;
+}
+
+//	Does this tid carry epg summary data
+bool CSkyManager::DoesTidCarryChannelNetworkData(int tid)
+{
+	return tid == PID_SKYUKIT_EPG_CHANNEL_TABLEID;
+}
+
+//	Does this pid carry epg data?
+bool CSkyManager::DoesPidCarryEpgData(int pid)
+{
+	return DoesPidCarryEpgTitleData(pid) || DoesPidCarryEpgSummaryData(pid);
+}
+
+//	Does this tid carry epg title data
+bool CSkyManager::DoesTidCarryEpgTitleData(int tid)
+{
+	return tid >= PID_SKYUKIT_EPG_TITLE_TABLEID_F && tid <= PID_SKYUKIT_EPG_TITLE_TABLEID_T;
+}
+
+//	Does this tid carry epg summary data
+bool CSkyManager::DoesTidCarryEpgSummaryData(int tid)
+{
+	return tid >= PID_SKYUKIT_EPG_SUMMARY_TABLEID_F && tid <= PID_SKYUKIT_EPG_SUMMARY_TABLEID_T;
+}
+
+//	Does the pid carry epg title data?
+bool CSkyManager::DoesPidCarryEpgTitleData(int pid)
+{
+	return (pid >= PID_SKYUKIT_EPG_TITLES_F && pid <= PID_SKYUKIT_EPG_TITLES_T);
+}
+
+//	Does the pid carry epg summary data?
+bool CSkyManager::DoesPidCarryEpgSummaryData(int pid)
+{
+	return (pid >= PID_SKYUKIT_EPG_SUMMARIES_F && pid <= PID_SKYUKIT_EPG_SUMMARIES_T);
+}
+
+//	Gets the bouquet with the specified id
+SkyBouquet* CSkyManager::GetBouquet(unsigned short bouquetId)
+{
+	Mediaportal::CEnterCriticalSection enter(criticalSection);
+
+	SkyBouquet* returnBouquet = NULL;
+
+	//	Try to find a lookup collection for this bouquet id
+	map<unsigned short, SkyBouquet*>::iterator bouquetIterator = bouquets.find(bouquetId);
+	
+	//	Create a new lookup for this channel if one does not exist yet, else get existing from iterator
+	if(bouquetIterator == bouquets.end())
+	{
+		returnBouquet = new SkyBouquet(bouquetId);
+		bouquets.insert(pair<unsigned short, SkyBouquet*>(bouquetId, returnBouquet));
+	}
+	else
+		returnBouquet = bouquetIterator->second;
+
+	return returnBouquet;
+}
+
+//	Are all bouquets now populated?
+bool CSkyManager::AreAllBouquetsPopulated()
+{
+	Mediaportal::CEnterCriticalSection enter(criticalSection);
+
+	return (bouquets.size() > 0) && (bouquets.size() == numberBouquetsPopulated);
+}
+
+//	Are all epg titles populated?
+bool CSkyManager::AreAllTitlesPopulated()
+{
+	return completedTitleDataCarousels.size() == (PID_SKYUKIT_EPG_TITLES_T - PID_SKYUKIT_EPG_TITLES_F + 1);
+}
+
+//	Are all epg summaries populated?
+bool CSkyManager::AreAllSummariesPopulated()
+{
+	return completedSummaryDataCarousels.size() == (PID_SKYUKIT_EPG_SUMMARIES_T - PID_SKYUKIT_EPG_SUMMARIES_F + 1);
+}
+
+//	Notifys the manager that a bouquet is now fully populated
+void CSkyManager::NotifyBouquetPopulated()
+{
+	Mediaportal::CEnterCriticalSection enter(criticalSection);
+
+	numberBouquetsPopulated++;
+	
+	int bouquetsFound = bouquets.size();
+
+	//	If fully populated
+	if(bouquetsFound == numberBouquetsPopulated)
+		LogDebug("CSkyManager - Channel & bouquet scan complete.  Found a total of %d channels in %d bouquets", GetChannelCount(), bouquetsFound);
+}
+
+//	Gets the number of channels found
+unsigned int CSkyManager::GetChannelCount()
+{
+	Mediaportal::CEnterCriticalSection enter(criticalSection);
+
+	return channels.size();
+}
+
+//	Gets the existing, or creates a new channel with the specified id
+SkyChannel* CSkyManager::GetChannel(unsigned short channelId)
+{
+	Mediaportal::CEnterCriticalSection enter(criticalSection);
+	
+	SkyChannel* returnChannel = NULL;
+
+	//	Try to find a lookup collection for this channel id
+	map<unsigned short, SkyChannel*>::iterator channelIterator = channels.find(channelId);
+	
+	//	Create a new lookup for this channel if one does not exist yet, else get existing from iterator
+	if(channelIterator == channels.end())
+	{
+		returnChannel = new SkyChannel(channelId);
+		channels.insert(pair<unsigned short, SkyChannel*>(channelId, returnChannel));
+	}
+	else
+		returnChannel = channelIterator->second;
+
+	return returnChannel;
+}
+
+//	Gets the epg event count
+unsigned int CSkyManager::GetEpgEventCount()
+{
+	Mediaportal::CEnterCriticalSection enter(criticalSection);
+
+	map<unsigned short, SkyChannel*>::iterator channelIterator;
+
+	int eventCount = 0;
+
+	//	Loop through all channels
+	for(channelIterator = channels.begin(); channelIterator != channels.end(); channelIterator++)
+	{
+		if(channelIterator->second->events != NULL)
+			eventCount += channelIterator->second->events->size();
+	}
+
+	return eventCount;
+}
+
+//	Gets the existing, or creates a new epg event with the specified ids
+SkyEpgEvent* CSkyManager::GetEpgEvent(unsigned short channelId, unsigned short eventId)
+{
+	Mediaportal::CEnterCriticalSection enter(criticalSection);
+
+	//	Get the channel that this epg event applies to
+	SkyChannel* channel = GetChannel(channelId);
+
+	//	Initialize the events collection if null
+	if(channel->events == NULL)
+		channel->events = new map<unsigned short, SkyEpgEvent*>();
+
+	SkyEpgEvent* returnEvent = NULL;
+
+	//	Try to find a lookup collection for this channel id
+	map<unsigned short, SkyEpgEvent*>::iterator eventIterator = channel->events->find(eventId);
+	
+	//	Create a new lookup for this channel if one does not exist yet, else get existing from iterator
+	if(eventIterator == channel->events->end())
+	{
+		returnEvent = new SkyEpgEvent(eventId);
+		channel->events->insert(pair<unsigned short, SkyEpgEvent*>(eventId, returnEvent));
+	}
+	else
+		returnEvent = eventIterator->second;
+
+	return returnEvent;
+
+}
+
+//	Gets the current country id
+unsigned int CSkyManager::GetCurrentCountryId()
+{
+	return currentCountryId;
+}
+
+//	Decodes a huffman buffer
+byte* CSkyManager::DecodeHuffmanData(byte* buffer, int length)
+{
+	Mediaportal::CEnterCriticalSection enter(criticalSection);
+	
+	//	First 2 bits are the huffman table id
+	byte huffmanTableId = (buffer[0] & 0xC0) >> 6;
+
+	//	Work out the appropriate huffman table
+	//	0 = firmware table
+	//	1 = dynamic broadcast table 1 (from Pid 0x85)
+	//	2 = dynamic broadcast table 2 (from Pid 0x85)
+	CHuffmanTree* decodeHuffmanTree = NULL;
+
+	if(huffmanTableId == 0)
+	{
+		//	Using firmware trees
+		map<unsigned short, CHuffmanTree*>::iterator huffmanTreeIterator = countryFirmwareHuffmanTrees.find(currentCountryId);
+
+		if(huffmanTreeIterator == countryFirmwareHuffmanTrees.end())
+		{
+			LogError("CSkyManager::DecodeHuffmanData() - Failed to find firmware huffman tree");
+			return NULL;			
+		}
+
+		decodeHuffmanTree = huffmanTreeIterator->second;
+	}
+	else
+	{
+		numberFailedHuffmanDecodes++;
+		return NULL;
+	}
+
+	if(decodeHuffmanTree == NULL)
+	{
+		LogError("CSkyManager::DecodeHuffmanData() - Failed to locate huffman tree to decode data");
+		return NULL;
+	}
+
+	int decodedLength = decodeHuffmanTree->Decode(buffer, length, 2, &huffmanDecodeBuffer[0], HUFFMAN_DECODE_BUFFER_SIZE);
+
+	//	Allocate a buffer large enough for the decoded buffer
+	byte* copiedDecode = (byte*) malloc((decodedLength + 1) * sizeof(byte));
+
+	memcpy(copiedDecode, huffmanDecodeBuffer, decodedLength);
+	copiedDecode[decodedLength] = '\0';
+
+	return copiedDecode;
+}
+
+//	Notifys the manager that a title event has been received
+void CSkyManager::OnTitleReceived(unsigned short pid, unsigned int titleChannelEventUnionId)
+{
+	Mediaportal::CEnterCriticalSection enter(criticalSection);
+
+	//	Have we added the start of this pid's carousel yet?
+	map<unsigned short, unsigned int>::iterator it = titleDataCarouselStartLookup.find(pid);
+
+	//	This pid is just starting
+	if(it == titleDataCarouselStartLookup.end())
+	{
+		titleDataCarouselStartLookup.insert(pair<unsigned short, unsigned int>(pid, titleChannelEventUnionId));
+	}
+
+	//	Else test if we are now back round to the start of the title carousel
+	else
+	{
+		if(it->second == titleChannelEventUnionId)
+		{
+			completedTitleDataCarousels.push_back(pid);
+
+			//	If all title pids have now completed, log a message
+			if(AreAllTitlesPopulated())
+				LogDebug("CSkyManager - Title decoding complete, found %u", titlesDecoded);
+					
+		}
+	}
+
+}
+
+//	Gets if the title data carousel on the specified pid is complete
+bool CSkyManager::IsTitleDataCarouselOnPidComplete(unsigned short pid)
+{
+	Mediaportal::CEnterCriticalSection enter(criticalSection);
+
+	vector<unsigned short>::iterator it = completedTitleDataCarousels.begin();
+
+	//	Loop through to see if this pid is complete
+	for(it = completedTitleDataCarousels.begin(); it != completedTitleDataCarousels.end(); it++)
+	{
+		if(*it == pid)
+			return true;
+	}
+
+	return false;
+}
+
+
+
+//	Notifys the manager that a summary event has been received
+void CSkyManager::OnSummaryReceived(unsigned short pid, unsigned int summaryChannelEventUnionId)
+{
+	Mediaportal::CEnterCriticalSection enter(criticalSection);
+
+	//	Have we added the start of this pid's carousel yet?
+	map<unsigned short, unsigned int>::iterator it = summaryDataCarouselStartLookup.find(pid);
+
+	//	This pid is just starting
+	if(it == summaryDataCarouselStartLookup.end())
+	{
+		summaryDataCarouselStartLookup.insert(pair<unsigned short, unsigned int>(pid, summaryChannelEventUnionId));
+	}
+
+	//	Else test if we are now back round to the start of the title carousel
+	else
+	{
+		if(it->second == summaryChannelEventUnionId)
+		{
+			completedSummaryDataCarousels.push_back(pid);
+
+			//	If all title pids have now completed, log a message
+			if(AreAllSummariesPopulated())
+				LogDebug("CSkyManager - Summary decoding complete, found %u", summariesDecoded);
+		}
+	}
+
+}
+
+//	Gets if the title data carousel on the specified pid is complete
+bool CSkyManager::IsSummaryDataCarouselOnPidComplete(unsigned short pid)
+{
+	Mediaportal::CEnterCriticalSection enter(criticalSection);
+
+	vector<unsigned short>::iterator it = completedSummaryDataCarousels.begin();
+
+	//	Loop through to see if this pid is complete
+	for(it = completedSummaryDataCarousels.begin(); it != completedSummaryDataCarousels.end(); it++)
+	{
+		if(*it == pid)
+			return true;
+	}
+
+	return false;
+}
+
+//	Fired when a title is decoded
+void CSkyManager::OnTitleDecoded()
+{
+	titlesDecoded++;
+}
+
+//	Fired when a summary is decoded
+void CSkyManager::OnSummaryDecoded()
+{
+	summariesDecoded++;
+}
+
+
+//	Fired when the epg callback is triggered
+void CSkyManager::OnEpgCallback()
+{
+	//	Report any failed items
+	if(numberFailedHuffmanDecodes > 0)
+		LogDebug("CSkyManager::OnEpgCallback() - %d huffman encoded items could not be processed as they require an unknown table", numberFailedHuffmanDecodes);
+}
+//	Resets the epg retrieval iterators
+void CSkyManager::ResetEpgRetrieval()
+{
+	Mediaportal::CEnterCriticalSection enter(criticalSection);
+
+	retrievalReset = true;
+}
+
+//	Gets the next sky epg channel information
+void CSkyManager::GetNextSkyEpgChannel(unsigned char *atEnd, unsigned short *channelId, unsigned short *networkId, unsigned short *transportId, unsigned short *serviceId)
+{
+	Mediaportal::CEnterCriticalSection enter(criticalSection);
+
+	//	If the retrieval was reset, we want to read the first channel
+	if(retrievalReset)
+	{
+		epgRetrievalChannelsIt = channels.begin();
+		retrievalReset = false;
+	}
+	else
+		epgRetrievalChannelsIt++;
+
+	//	Skip this channel if it has no events defined
+	while(epgRetrievalChannelsIt != channels.end() && (epgRetrievalChannelsIt->second->events == NULL || (epgRetrievalChannelsIt->second->events != NULL && epgRetrievalChannelsIt->second->events->empty())))
+		epgRetrievalChannelsIt++;
+
+	//	If we are now at the end, send back the is last channel flag
+	if(epgRetrievalChannelsIt == channels.end())
+	{
+		*atEnd = 1;
+		return;
+	}
+
+
+	SkyChannel* channel = epgRetrievalChannelsIt->second;
+
+	//	If the channel is null, log error
+	if(channel == NULL)
+	{
+		LogDebug("CSkyManager::GetNextSkyEpgChannel() - Channel is null unexpectedly");
+		*atEnd = 2;
+		return;
+	}
+
+	*channelId = channel->channelId;
+	*networkId = channel->networkId;
+	*transportId = channel->transportId;
+	*serviceId = channel->serviceId;
+
+	//	Start the events iterator at the first event for this channel
+	epgRetrievalChannelEventsIt = channel->events->begin();
+}
+
+//	Gets the next sky epg channel event information
+void CSkyManager::GetNextSkyEpgChannelEvent(unsigned char* atEnd, unsigned short* eventId, unsigned short* mjdStart, unsigned int* startTime, unsigned int* duration, unsigned char** title, unsigned char** summary, unsigned char** theme, unsigned short* seriesId, byte* seriesTermination)
+{
+	Mediaportal::CEnterCriticalSection enter(criticalSection);
+
+	//	If there are no events for this channel, or we are already at the end
+	if(epgRetrievalChannelsIt->second->events == NULL || epgRetrievalChannelsIt->second->events->empty() || epgRetrievalChannelEventsIt == epgRetrievalChannelsIt->second->events->end())
+	{
+		*atEnd = 1;
+		return;
+	}
+
+	SkyEpgEvent* epgEvent = epgRetrievalChannelEventsIt->second;
+
+	//	If the epg event is null, log error
+	if(epgEvent == NULL)
+	{
+		LogDebug("CSkyManager::GetNextSkyEpgChannelEvent() - Epg event is null unexpectedly");
+		*atEnd = 2;
+		return;
+	}
+
+	//	Set the return fields
+	*eventId = epgEvent->eventId;
+	*mjdStart = epgEvent->mjdStart;
+	*startTime = epgEvent->startTime;
+	*duration = epgEvent->duration;
+	*title = epgEvent->title;
+	*summary = epgEvent->summary;
+	*theme = epgEvent->theme;
+	*seriesId = epgEvent->seriesId;
+
+	//	Series termination is only applicable if series id is available
+	if(epgEvent->seriesId > NULL)
+		*seriesTermination = epgEvent->seriesTermination;
+	else
+		*seriesTermination = 0;
+
+	//	Move to next epg event for this channel
+	epgRetrievalChannelEventsIt++;
+
+}
Index: DirectShowFilters/TsWriter/source/SkyManager.h
===================================================================
--- DirectShowFilters/TsWriter/source/SkyManager.h	(revision 0)
+++ DirectShowFilters/TsWriter/source/SkyManager.h	(revision 0)
@@ -0,0 +1,319 @@
+/* 
+ *	Copyright (C) 2006-2008 Team MediaPortal
+ *	http://www.team-mediaportal.com
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include <map>
+#include <windows.h>
+#include "SkyEpgParser.h"
+#include "SkyChannelParser.h"
+#include "HuffmanTree.h"
+#include "CriticalSection.h"
+#include "EnterCriticalSection.h"
+
+using namespace std;
+
+//	External logging method
+extern void LogDebug(const char *fmt, ...);
+
+
+#define MAX_LOGGED_ERRORS	20
+
+
+#define SKY_COUNTRY_UK	0x01
+#define SKY_COUNTRY_IT	0x02
+
+
+//	Sky UK & IT use pid 0x11 for epg channel information
+#define PID_SKYUKIT_EPG_CHANNEL_INFORMATION		0x11
+
+//	Sky UK & IT use pids 0x30-0x37 for epg item titles & 0x40-0x47 for normal summaries & 0x50-0x57 for box office and adult summaries
+#define PID_SKYUKIT_EPG_TITLES_F     0x30
+#define PID_SKYUKIT_EPG_TITLES_T     0x37
+#define PID_SKYUKIT_EPG_SUMMARIES_F  0x40
+#define PID_SKYUKIT_EPG_SUMMARIES_T  0x47
+
+#define PID_SKYUKIT_EPG_CHANNEL_TABLEID		0x4A
+#define PID_SKYUKIT_EPG_TITLE_TABLEID_F		0xA0
+#define PID_SKYUKIT_EPG_TITLE_TABLEID_T		0xA3
+#define PID_SKYUKIT_EPG_SUMMARY_TABLEID_F	0xA8
+#define PID_SKYUKIT_EPG_SUMMARY_TABLEID_T	0xAB
+
+
+#define HUFFMAN_DECODE_BUFFER_SIZE		8192
+
+
+typedef struct SkyEpgEvent;
+
+typedef struct SkyBouquet
+{
+	unsigned short bouquetId;
+	byte firstReceivedSectionNumber;
+	bool isInitialized;
+	bool isPopulated;
+
+	SkyBouquet::SkyBouquet(unsigned short newBouquetId)
+	{
+		bouquetId = newBouquetId;
+		firstReceivedSectionNumber = NULL;
+		isInitialized = false;
+		isPopulated = false;
+	}
+
+}SkyBouquet;
+
+typedef struct SkyChannel
+{
+	unsigned short channelId;
+
+	unsigned short networkId;
+	unsigned short transportId;
+	unsigned short serviceId;
+	unsigned short epgChannelNumber;
+
+	bool isPopulated;
+
+	map<unsigned short, SkyEpgEvent*>* events;
+
+	SkyChannel::SkyChannel(unsigned short _channelId)
+	{
+		channelId = _channelId;
+
+		networkId = NULL;
+		transportId = NULL;
+		serviceId = NULL;
+		epgChannelNumber = NULL;
+
+		isPopulated = false;
+
+		events = NULL;
+	}
+
+}SkyChannel;
+
+//	Sky epg event
+typedef struct SkyEpgEvent
+{
+	unsigned short eventId;
+
+	unsigned short mjdStart;
+	unsigned int startTime;
+	unsigned int duration;
+	unsigned short seriesId;
+	unsigned int seriesTermination;
+
+	byte* title;
+	byte* summary;
+	byte* theme;
+
+	bool isPopulated;
+
+	SkyEpgEvent::SkyEpgEvent(unsigned short _eventId)
+	{
+		eventId = _eventId;
+
+		mjdStart = NULL;
+		startTime = NULL;
+		duration = NULL;
+		seriesId = NULL;
+		seriesTermination = NULL;
+
+		title = NULL;
+		summary = NULL;
+		theme = NULL;
+
+		isPopulated = false;
+	}
+};
+
+
+class CSkyManager
+{
+public:
+	//	Constr
+	CSkyManager();
+	
+	//	Flzr
+	~CSkyManager();
+
+	//	Logs an error a maximum number of times
+	void LogError(const char* message);
+
+	//	Resets the manager
+	void Reset();
+
+	//	Activates the epg grabber for the specified Sky country
+	void ActivateEpgGrabber(unsigned short activateCountryId);
+
+	//	De-activates the epg grabber
+	void DeActivateEpgGrabber();
+
+	//	Is the epg grabbing active
+	bool IsEpgGrabbingActive();
+
+	//	Is the epg grabbing finished
+	bool IsEpgGrabbingFinished();
+
+	//	Has EPG grabbing been aborted through too many errors?
+	bool HasEpgGrabbingAborted();
+	
+	//	Does this pid carry channel network data?
+	bool DoesPidCarryChannelNetworkData(int pid);
+
+	//	Does this tid carry channel network data?
+	bool DoesTidCarryChannelNetworkData(int tid);
+
+	//	Does this pid carry epg data?
+	bool DoesPidCarryEpgData(int pid);
+
+	//	Does the pid carry epg title data?
+	bool DoesPidCarryEpgTitleData(int pid);
+	
+	//	Does the pid carry epg summary data?
+	bool DoesPidCarryEpgSummaryData(int pid);
+
+	//	Does the table id carry epg title data?
+	bool DoesTidCarryEpgTitleData(int tid);
+
+	//	Does the table id carry
+	bool DoesTidCarryEpgSummaryData(int tid);
+
+	//	Fired when a new ts packet is received
+	void OnTsPacket(CTsHeader& header, byte* tsPacket);
+
+	//	Notifys the manager that the epg channel network data is fully populated
+	void NotifyEpgChannelNetworkDataFullyPopulated();
+
+	//	Gets the bouquet with the specified id
+	SkyBouquet* GetBouquet(unsigned short bouquestId);
+
+	//	Gets the channel with the specified id
+	SkyChannel* GetChannel(unsigned short channelId);
+
+	//	Gets the epg event with the specified ids
+	SkyEpgEvent* GetEpgEvent(unsigned short channelId, unsigned short eventId);
+	
+	//	Gets the current country id
+	unsigned int GetCurrentCountryId();
+
+	//	Are all bouquets populated?
+	bool AreAllBouquetsPopulated();
+
+	//	Are all epg titles populated
+	bool AreAllTitlesPopulated();
+
+	//	Are all epg summaries populated?
+	bool AreAllSummariesPopulated();
+	
+	//	Notifys that a bouquet is now fully populated
+	void NotifyBouquetPopulated();
+
+	//	Gets the channel count
+	unsigned int GetChannelCount();
+
+	//	Gets the epg event count
+	unsigned int GetEpgEventCount();
+	
+	//	Notifys the manager that a title event has been received
+	void OnTitleReceived(unsigned short pid, unsigned int titleChannelEventUnionId);
+
+	//	Gets if the data carousel for the specified pid is now complete
+	bool IsTitleDataCarouselOnPidComplete(unsigned short pid);
+
+	//	Notifys the manager that a summary event has been received
+	void OnSummaryReceived(unsigned short pid, unsigned int summaryChannelEventUnionId);
+
+	//	Gets if the data carousel for the specified pid is now complete
+	bool IsSummaryDataCarouselOnPidComplete(unsigned short pid);
+
+	//	Notifies the manager that a title has been decoded
+	void OnTitleDecoded();
+
+	//	Nofitied the manager that a summary has been decoded
+	void OnSummaryDecoded();
+
+	//	Fired when the epg callback is triggered
+	void OnEpgCallback();
+
+	//	Decodes a huffman buffer
+	byte* DecodeHuffmanData(byte* buffer, int length);
+
+	//	Retrieval epg methods
+
+	//	Resets the retrieval pointers
+	void ResetEpgRetrieval();
+
+	//	Gets the next epg channel
+	void GetNextSkyEpgChannel(unsigned char* atEnd, unsigned short* channelId, unsigned short* networkId, unsigned short* transportId, unsigned short* serviceId);
+
+	//	Gets the next epg channel event
+	void GetNextSkyEpgChannelEvent(unsigned char* atEnd, unsigned short* eventId, unsigned short* mjdStart, unsigned int* startTime, unsigned int* duration, unsigned char** title, unsigned char** summary, unsigned char** theme, unsigned short* seriesId, byte* seriesTermination);
+
+	//	Critical section
+	Mediaportal::CCriticalSection criticalSection;
+
+private:
+
+	
+	bool isInitialized;
+	bool epgFirmwareHuffmanTreesPopulated;
+	bool isEpgGrabbingActive;
+	bool retrievalReset;
+	bool epgGrabbingAbortedThroughTooManyErrors;
+
+	unsigned int numberErrorsLogged;
+	unsigned int numberFailedHuffmanDecodes;
+	unsigned int numberBouquetsPopulated;
+
+	unsigned int currentCountryId;
+
+	byte huffmanDecodeBuffer[HUFFMAN_DECODE_BUFFER_SIZE];
+
+	CSkyEpgParser* skyEpgParser;
+	CSkyChannelParser* skyChannelParser;
+
+	map<unsigned short, CHuffmanTree*> countryFirmwareHuffmanTrees;
+
+	map<unsigned short, SkyBouquet*> bouquets;
+
+	map<unsigned short, SkyChannel*> channels;
+
+	//	Epg retrieval iterators
+	map<unsigned short, SkyChannel*>::iterator epgRetrievalChannelsIt;
+	map<unsigned short, SkyEpgEvent*>::iterator epgRetrievalChannelEventsIt;
+	
+	//	Lookup of the first piece of title data lifted of the pid carousel, indexed on pid
+	map<unsigned short, unsigned int> titleDataCarouselStartLookup;
+
+	//	Completed title carousels (pid)
+	vector<unsigned short> completedTitleDataCarousels;
+	
+	//	Lookup of the first piece of title data lifted of the pid carousel, indexed on pid
+	map<unsigned short, unsigned int> summaryDataCarouselStartLookup;
+
+	//	Completed summary carousels (pid)
+	vector<unsigned short> completedSummaryDataCarousels;
+
+	int titlesDecoded;
+	int summariesDecoded;
+
+	//	Initializes the epg huffman trees
+	bool InitializeEpgFirmwareHuffmanTrees();
+
+};
Index: DirectShowFilters/TsWriter/source/SkyThemes.h
===================================================================
--- DirectShowFilters/TsWriter/source/SkyThemes.h	(revision 0)
+++ DirectShowFilters/TsWriter/source/SkyThemes.h	(revision 0)
@@ -0,0 +1,541 @@
+/* 
+ *	Copyright (C) 2006-2008 Team MediaPortal
+ *	http://www.team-mediaportal.com
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+char* ukThemes[] = 
+{
+"No Category",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"Shopping",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"Children",
+"Children - Cartoons",
+"Children - Comedy",
+"Children - Drama",
+"Children - Educational",
+"Children - Under 5",
+"Children - Factual",
+"Children - Magazine",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"Entertainment",
+"Entertainment - Action",
+"Entertainment - Comedy",
+"Entertainment - Detective",
+"Entertainment - Drama",
+"Entertainment - Game Show",
+"Entertainment - Sci-FI",
+"Entertainment - Soap",
+"Entertainment - Animation",
+"Entertainment - Chat Show",
+"Entertainment - Cooking",
+"Entertainment - Factual",
+"Entertainment - Fashion",
+"Entertainment - Gardening",
+"Entertainment - Travel",
+"Entertainment - Technology",
+"Entertainment - Arts",
+"Entertainment - Lifestyle",
+"Entertainment - Home",
+"Entertainment - Magazine",
+"Entertainment - Medical",
+"Entertainment - Review",
+"Entertainment - Antiques",
+"Entertainment - Motors",
+"Entertainment - Art&Lit",
+"Entertainment - Ballet",
+"Entertainment - Opera",
+"",
+"",
+"",
+"",
+"",
+"Music",
+"Music - Classical ",
+"Music - Folk and Country",
+"Music - National Music",
+"Music - Jazz",
+"Music - Opera",
+"Music - Rock&Pop",
+"Music - Alternative Music",
+"Music - Events",
+"Music - Club and Dance",
+"Music - Hip Hop",
+"Music - Soul/R&B",
+"Music - Dance",
+"",
+"",
+"",
+"Music - Features",
+"",
+"",
+"",
+"",
+"Music - Lifestyle",
+"Music - News and Weather",
+"Music - Easy Listening",
+"Music - Discussion",
+"Music - Entertainment",
+"Music - Religious",
+"",
+"",
+"",
+"",
+"",
+"News & Documentaries",
+"News & Documentaries - Business",
+"News & Documentaries - World Cultures",
+"News & Documentaries - Adventure",
+"News & Documentaries - Biography",
+"News & Documentaries - Educational",
+"News & Documentaries - Feature",
+"News & Documentaries - Politics",
+"News & Documentaries - News",
+"News & Documentaries - Nature",
+"News & Documentaries - Religious",
+"News & Documentaries - Science",
+"News & Documentaries - Showbiz",
+"News & Documentaries - War Documentary",
+"News & Documentaries - Historical",
+"News & Documentaries - Ancient",
+"News & Documentaries - Transport",
+"News & Documentaries - Docudrama",
+"News & Documentaries - World Affairs",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"Movie",
+"Movie - Action",
+"Movie - Animation",
+"",
+"Movie - Comedy",
+"Movie - Family",
+"Movie - Drama",
+"",
+"Movie - Sci-Fi",
+"Movie - Thriller",
+"Movie - Horror",
+"Movie - Romance",
+"Movie - Musical",
+"Movie - Mystery",
+"Movie - Western",
+"Movie - Factual",
+"Movie - Fantasy",
+"Movie - Erotic",
+"Movie - Adventure",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"Sports - Other",
+"Sports - American Football",
+"Sports - Athletics",
+"Sports - Baseball",
+"Sports - Basketball",
+"Sports - Boxing",
+"Sports - Cricket",
+"Sports - Fishing",
+"Sports - Football",
+"Sports - Golf",
+"Sports - Ice Hockey",
+"Sports - Motor Sport",
+"Sports - Racing",
+"Sports - Rugby",
+"Sports - Equestrian",
+"Sports - Winter Sports",
+"Sports - Snooker / Pool",
+"Sports - Tennis",
+"Sports - Wrestling",
+"Sports - Darts",
+"Sports - Watersports",
+"Sports - Extreme",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+""
+};
+
+
+char* itThemes[] = 
+{
+"Non Definito",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"Intrattenimento",
+"Intrattenimento - Fiction",
+"Intrattenimento - Sit Com",
+"Intrattenimento - Show",
+"Intrattenimento - Telefilm",
+"Intrattenimento - Soap Opera",
+"Intrattenimento - Telenovela",
+"Intrattenimento - Fantascienza",
+"Intrattenimento - Animazione",
+"Intrattenimento - Giallo",
+"Intrattenimento - Drammatico",
+"Intrattenimento - Romantico",
+"Intrattenimento - Miniserie",
+"Intrattenimento - Spettacolo",
+"Intrattenimento - Quiz",
+"Intrattenimento - Talk Show",
+"Intrattenimento - Variet�",
+"Intrattenimento - Festival",
+"Intrattenimento - Teatro",
+"Intrattenimento - Gioco",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"Sport",
+"Sport - Calcio",
+"Sport - Tennis",
+"Sport - Motori",
+"Sport - Altri",
+"Sport - Baseball",
+"Sport - Ciclismo",
+"Sport - Rugby",
+"Sport - Basket",
+"Sport - Boxe",
+"Sport - Atletica",
+"Sport - Football USA",
+"Sport - Hockey",
+"Sport - Sci",
+"Sport - Equestri",
+"Sport - Golf",
+"Sport - Nuoto",
+"Sport - Wrestling",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"Film",
+"Film - Drammatico",
+"Film - Commedia",
+"Film - Romantico",
+"Film - Azione",
+"Film - Fantascienza",
+"Film - Western",
+"Film - Comico",
+"Film - Fantastico",
+"Film - Avventura",
+"Film - Poliziesco",
+"Film - Guerra",
+"Film - Horror",
+"Film - Animazione",
+"Film - Thriller",
+"Film - Musicale",
+"Film - Corto",
+"Film - Cortometraggio",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"Mondo e Tendenze",
+"Mondo e Tendenze - Natura",
+"Mondo e Tendenze - Arte e Cultura",
+"Mondo e Tendenze - Lifestyle",
+"Mondo e Tendenze - Viaggi",
+"Mondo e Tendenze - Documentario",
+"Mondo e Tendenze - Societ�",
+"Mondo e Tendenze - Scienza",
+"Mondo e Tendenze - Storia",
+"Mondo e Tendenze - Sport",
+"Mondo e Tendenze - Pesca",
+"Mondo e Tendenze - Popoli",
+"Mondo e Tendenze - Cinema",
+"Mondo e Tendenze - Musica",
+"Mondo e Tendenze - Hobby",
+"Mondo e Tendenze - Caccia",
+"Mondo e Tendenze - Reportage",
+"Mondo e Tendenze - Magazine",
+"Mondo e Tendenze - Magazine Cultura",
+"Mondo e Tendenze - Magazine Scienza",
+"Mondo e Tendenze - Politica",
+"Mondo e Tendenze - Magazine Cinema",
+"Mondo e Tendenze - Magazine Sport",
+"Mondo e Tendenze - Attualit�",
+"Mondo e Tendenze - Moda",
+"Mondo e Tendenze - Economia",
+"Mondo e Tendenze - Magazine Caccia e Pesca",
+"Mondo e Tendenze - Magazine Viaggi",
+"Mondo e Tendenze - Magazine Natura",
+"Mondo e Tendenze - Magazine Musica",
+"Mondo e Tendenze - Religione",
+"Mondo e Tendenze - Televendita",
+"Informazione",
+"Informazione - Notiziario",
+"Informazione - Sport",
+"Informazione - Economia",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"Ragazzi e Musica",
+"Ragazzi e Musica - Bambini",
+"Ragazzi e Musica - Ragazzi",
+"Ragazzi e Musica - Cartoni Animati",
+"Ragazzi e Musica - Musica",
+"Ragazzi e Musica - Film Animazione",
+"Ragazzi e Musica - Film",
+"Ragazzi e Musica - Telefilm",
+"Ragazzi e Musica - Magazine",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"Ragazzi e Musica - Danza",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"Altri Programmi",
+"Altri Programmi - Educational",
+"Altri Programmi - Regionale",
+"Altri Programmi - Shopping",
+"",
+"Altri Programmi - Inizio e Fine Trasmissioni",
+"Altri Programmi - Eventi Speciali",
+"Altri Programmi - Film per Adulti",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+"",
+""
+};
Index: mediaportal/Configuration/Sections/TV.cs
===================================================================
--- mediaportal/Configuration/Sections/TV.cs	(revision 27484)
+++ mediaportal/Configuration/Sections/TV.cs	(working copy)
@@ -22,6 +22,7 @@
 using System.Windows.Forms;
 using MediaPortal.Profile;
 using MediaPortal.UserInterface.Controls;
+using System.Collections.Generic;
 
 #pragma warning disable 108
 
@@ -42,8 +43,16 @@
     private MPLabel label8;
     private MPComboBox cbDeinterlace;
     private MPGroupBox mpGroupBoxAdditional;
+    private MPGroupBox gbRecording;
+    private MPListView lvIncludeScheduleTypes;
+    private MPCheckBox cbUseQuickRecordMenu;
+    private ColumnHeader clIncludedSchedules;
+    private MPButton btQuickRecordScheduleUp;
+    private MPButton btQuickRecordScheduleDown;
     public int pluginVersion;
 
+    private readonly Dictionary<ListViewItem, string> _listItemScheduleLookup = new Dictionary<ListViewItem, string>();
+
     public TV()
       : this("TV") {}
 
@@ -84,10 +93,17 @@
       this.label8 = new MediaPortal.UserInterface.Controls.MPLabel();
       this.cbDeinterlace = new MediaPortal.UserInterface.Controls.MPComboBox();
       this.mpGroupBoxAdditional = new MediaPortal.UserInterface.Controls.MPGroupBox();
+      this.gbRecording = new MediaPortal.UserInterface.Controls.MPGroupBox();
+      this.btQuickRecordScheduleDown = new MediaPortal.UserInterface.Controls.MPButton();
+      this.btQuickRecordScheduleUp = new MediaPortal.UserInterface.Controls.MPButton();
+      this.lvIncludeScheduleTypes = new MediaPortal.UserInterface.Controls.MPListView();
+      this.clIncludedSchedules = new System.Windows.Forms.ColumnHeader();
+      this.cbUseQuickRecordMenu = new MediaPortal.UserInterface.Controls.MPCheckBox();
       this.groupBox3.SuspendLayout();
       ((System.ComponentModel.ISupportInitialize)(this.channelNumberMaxLengthNumUpDn)).BeginInit();
       this.groupBox5.SuspendLayout();
       this.mpGroupBoxAdditional.SuspendLayout();
+      this.gbRecording.SuspendLayout();
       this.SuspendLayout();
       // 
       // radioButton1
@@ -243,8 +259,75 @@
       this.mpGroupBoxAdditional.TabStop = false;
       this.mpGroupBoxAdditional.Text = "Additional settings";
       // 
+      // gbRecording
+      // 
+      this.gbRecording.Controls.Add(this.btQuickRecordScheduleDown);
+      this.gbRecording.Controls.Add(this.btQuickRecordScheduleUp);
+      this.gbRecording.Controls.Add(this.lvIncludeScheduleTypes);
+      this.gbRecording.Controls.Add(this.cbUseQuickRecordMenu);
+      this.gbRecording.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+      this.gbRecording.Location = new System.Drawing.Point(4, 181);
+      this.gbRecording.Name = "gbRecording";
+      this.gbRecording.Size = new System.Drawing.Size(267, 243);
+      this.gbRecording.TabIndex = 17;
+      this.gbRecording.TabStop = false;
+      this.gbRecording.Text = "Recording";
+      // 
+      // btQuickRecordScheduleDown
+      // 
+      this.btQuickRecordScheduleDown.Location = new System.Drawing.Point(225, 130);
+      this.btQuickRecordScheduleDown.Name = "btQuickRecordScheduleDown";
+      this.btQuickRecordScheduleDown.Size = new System.Drawing.Size(34, 23);
+      this.btQuickRecordScheduleDown.TabIndex = 3;
+      this.btQuickRecordScheduleDown.Text = "Dw";
+      this.btQuickRecordScheduleDown.UseVisualStyleBackColor = true;
+      this.btQuickRecordScheduleDown.Click += new System.EventHandler(this.btQuickRecordScheduleDown_Click);
+      // 
+      // btQuickRecordScheduleUp
+      // 
+      this.btQuickRecordScheduleUp.Location = new System.Drawing.Point(225, 101);
+      this.btQuickRecordScheduleUp.Name = "btQuickRecordScheduleUp";
+      this.btQuickRecordScheduleUp.Size = new System.Drawing.Size(34, 23);
+      this.btQuickRecordScheduleUp.TabIndex = 2;
+      this.btQuickRecordScheduleUp.Text = "Up";
+      this.btQuickRecordScheduleUp.UseVisualStyleBackColor = true;
+      this.btQuickRecordScheduleUp.Click += new System.EventHandler(this.btQuickRecordScheduleUp_Click);
+      // 
+      // lvIncludeScheduleTypes
+      // 
+      this.lvIncludeScheduleTypes.AllowDrop = true;
+      this.lvIncludeScheduleTypes.AllowRowReorder = true;
+      this.lvIncludeScheduleTypes.CheckBoxes = true;
+      this.lvIncludeScheduleTypes.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+            this.clIncludedSchedules});
+      this.lvIncludeScheduleTypes.FullRowSelect = true;
+      this.lvIncludeScheduleTypes.Location = new System.Drawing.Point(16, 42);
+      this.lvIncludeScheduleTypes.MultiSelect = false;
+      this.lvIncludeScheduleTypes.Name = "lvIncludeScheduleTypes";
+      this.lvIncludeScheduleTypes.Size = new System.Drawing.Size(203, 182);
+      this.lvIncludeScheduleTypes.TabIndex = 1;
+      this.lvIncludeScheduleTypes.UseCompatibleStateImageBehavior = false;
+      this.lvIncludeScheduleTypes.View = System.Windows.Forms.View.Details;
+      // 
+      // clIncludedSchedules
+      // 
+      this.clIncludedSchedules.Text = "Include schedule types";
+      this.clIncludedSchedules.Width = 198;
+      // 
+      // cbUseQuickRecordMenu
+      // 
+      this.cbUseQuickRecordMenu.AutoSize = true;
+      this.cbUseQuickRecordMenu.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+      this.cbUseQuickRecordMenu.Location = new System.Drawing.Point(16, 19);
+      this.cbUseQuickRecordMenu.Name = "cbUseQuickRecordMenu";
+      this.cbUseQuickRecordMenu.Size = new System.Drawing.Size(191, 17);
+      this.cbUseQuickRecordMenu.TabIndex = 0;
+      this.cbUseQuickRecordMenu.Text = "Use quick record menu in TV guide";
+      this.cbUseQuickRecordMenu.UseVisualStyleBackColor = true;
+      // 
       // TV
       // 
+      this.Controls.Add(this.gbRecording);
       this.Controls.Add(this.mpGroupBoxAdditional);
       this.Controls.Add(this.groupBox5);
       this.Controls.Add(this.groupBox3);
@@ -256,6 +339,8 @@
       this.groupBox5.ResumeLayout(false);
       this.groupBox5.PerformLayout();
       this.mpGroupBoxAdditional.ResumeLayout(false);
+      this.gbRecording.ResumeLayout(false);
+      this.gbRecording.PerformLayout();
       this.ResumeLayout(false);
 
     }
@@ -286,6 +371,92 @@
           DeInterlaceMode = 3;
         }
         cbDeinterlace.SelectedIndex = DeInterlaceMode;
+
+        //  Load quick record menu options
+        cbUseQuickRecordMenu.Checked = xmlreader.GetValueAsBool("mytv", "usequickrecordmenu", false);
+
+        string selectedSchedulesValue = xmlreader.GetValueAsString("mytv", "selectedquickrecordschedules", string.Empty);
+
+        if (selectedSchedulesValue == null)
+          selectedSchedulesValue = string.Empty;
+
+        string[] scheduleOrder = xmlreader.GetValueAsString("mytv", "quickrecordscheduleorder", string.Empty).Split(new char[] { ',' });
+        List<string> scheduleOrderList = new List<string>(scheduleOrder);
+
+        if (!scheduleOrderList.Contains("Once")
+          || !scheduleOrderList.Contains("Daily")
+          || !scheduleOrderList.Contains("Weekly")
+          || !scheduleOrderList.Contains("EveryTimeOnThisChannel")
+          || !scheduleOrderList.Contains("EveryTimeOnEveryChannel")
+          || !scheduleOrderList.Contains("Weekends")
+          || !scheduleOrderList.Contains("WorkingDays")
+          || !scheduleOrderList.Contains("WeeklyEveryTimeOnThisChannel")
+          || !scheduleOrderList.Contains("SeriesLink")
+          )
+        {
+          scheduleOrderList = new List<string>() { "Once", "Daily", "Weekly", "EveryTimeOnThisChannel", "EveryTimeOnEveryChannel", "Weekends", "WorkingDays", "WeeklyEveryTimeOnThisChannel", "SeriesLink" };
+        }
+
+        _listItemScheduleLookup.Clear();
+        lvIncludeScheduleTypes.Items.Clear();
+
+        string[] selectedSchedules = xmlreader.GetValueAsString("mytv", "selectedquickrecordschedules", string.Empty).Split(new char[] { ',' });
+        List<string> selectedSchedulesList = new List<string>(selectedSchedules);
+
+        //  Populate the list
+        foreach (string scheduleItem in scheduleOrderList)
+        {
+          string scheduleDescription = string.Empty;
+
+          switch (scheduleItem)
+          {
+            case "Once":
+              scheduleDescription = "Once";
+              break;
+            case "Daily":
+              scheduleDescription = "Daily";
+              break;
+            case "Weekly":
+              scheduleDescription = "Weekly";
+              break;
+            case "EveryTimeOnThisChannel":
+              scheduleDescription = "Every time on this channel";
+              break;
+            case "EveryTimeOnEveryChannel":
+              scheduleDescription = "Every time on every channel";
+              break;
+            case "Weekends":
+              scheduleDescription = "Saturday/Sunday";
+              break;
+            case "WorkingDays":
+              scheduleDescription = "Monday-Friday";
+              break;
+            case "WeeklyEveryTimeOnThisChannel":
+              scheduleDescription = "Weekly every time on this channel";
+              break;
+            case "SeriesLink":
+              scheduleDescription = "Series link";
+              break;
+          }
+
+          if (scheduleDescription == string.Empty)
+            continue;
+
+          ListViewItem newItem = new ListViewItem();
+
+          newItem.Text = scheduleDescription;
+
+
+          if (selectedSchedulesList.Contains(scheduleItem))
+            newItem.Checked = true;
+          else
+            newItem.Checked = false;
+
+          lvIncludeScheduleTypes.Items.Add(newItem);
+          _listItemScheduleLookup.Add(newItem, scheduleItem);
+        }
+
+
       }
     }
 
@@ -307,6 +478,27 @@
         xmlwriter.SetValueAsBool("mytv", "byindex", byIndexCheckBox.Checked);
         xmlwriter.SetValueAsBool("mytv", "showchannelnumber", showChannelNumberCheckBox.Checked);
         xmlwriter.SetValue("mytv", "channelnumbermaxlength", channelNumberMaxLengthNumUpDn.Value);
+
+        //  Save quick record menu options
+        xmlwriter.SetValueAsBool("mytv", "usequickrecordmenu", cbUseQuickRecordMenu.Checked);
+
+        //  Build a list of selected items
+        string selectedItems = string.Empty;
+        string scheduleOrder = string.Empty;
+
+        foreach (ListViewItem item in lvIncludeScheduleTypes.Items)
+        {
+          string scheduleName = _listItemScheduleLookup[item];
+          scheduleOrder += (scheduleOrder != string.Empty ? "," : string.Empty) + scheduleName;
+
+          if (item.Checked)
+            selectedItems += (selectedItems != string.Empty ? "," : string.Empty) + scheduleName;
+
+        }
+
+        xmlwriter.SetValue("mytv", "quickrecordscheduleorder", scheduleOrder);
+        xmlwriter.SetValue("mytv", "selectedquickrecordschedules", selectedItems);
+
       }
     }
 
@@ -317,5 +509,45 @@
         cbTurnOnTv.Checked = true;
       }
     }
+
+    private void btQuickRecordScheduleUp_Click(object sender, EventArgs e)
+    {
+      if (lvIncludeScheduleTypes.SelectedItems.Count != 1)
+        return;
+
+      ListViewItem selectedItem = lvIncludeScheduleTypes.SelectedItems[0];
+
+      int selectedItemIndex = lvIncludeScheduleTypes.Items.IndexOf(selectedItem);
+
+      lvIncludeScheduleTypes.Items.RemoveAt(selectedItemIndex);
+
+      selectedItemIndex--;
+      if (selectedItemIndex < 0)
+        selectedItemIndex = 0;
+
+      lvIncludeScheduleTypes.Items.Insert(selectedItemIndex, selectedItem);
+      selectedItem.Selected = true;
+      lvIncludeScheduleTypes.Select();
+    }
+
+    private void btQuickRecordScheduleDown_Click(object sender, EventArgs e)
+    {
+      if (lvIncludeScheduleTypes.SelectedItems.Count != 1)
+        return;
+
+      ListViewItem selectedItem = lvIncludeScheduleTypes.SelectedItems[0];
+
+      int selectedItemIndex = lvIncludeScheduleTypes.Items.IndexOf(selectedItem);
+
+      lvIncludeScheduleTypes.Items.RemoveAt(selectedItemIndex);
+
+      selectedItemIndex++;
+      if (selectedItemIndex > lvIncludeScheduleTypes.Items.Count)
+        selectedItemIndex = lvIncludeScheduleTypes.Items.Count;
+
+      lvIncludeScheduleTypes.Items.Insert(selectedItemIndex, selectedItem);
+      selectedItem.Selected = true;
+      lvIncludeScheduleTypes.Select();
+    }
   }
 }
\ No newline at end of file
Index: mediaportal/MediaPortal.Base/language/strings_en.xml
===================================================================
--- mediaportal/MediaPortal.Base/language/strings_en.xml	(revision 27484)
+++ mediaportal/MediaPortal.Base/language/strings_en.xml	(working copy)
@@ -1965,5 +1965,9 @@
     <String id="200087">Mute</String>
     <String id="200090">Edition</String>
     <String id="200091">Chapter</String>
-	</Section>
-</Language>
+    <String id="200092">Record series</String>
+    <String id="200093">Quick record</String>
+    <String id="200094">Programme info</String>
+    <String id="200095">Series link on {0}</String>
+  </Section>
+</Language>
\ No newline at end of file
Index: TvEngine3/TVLibrary/Plugins/XmlTvImport/XmlTvImport.csproj
===================================================================
--- TvEngine3/TVLibrary/Plugins/XmlTvImport/XmlTvImport.csproj	(revision 27484)
+++ TvEngine3/TVLibrary/Plugins/XmlTvImport/XmlTvImport.csproj	(working copy)
@@ -2,7 +2,7 @@
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>9.0.30729</ProductVersion>
+    <ProductVersion>9.0.21022</ProductVersion>
     <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{158A88D6-FA0D-4D50-B9DC-D90E189206B0}</ProjectGuid>
     <OutputType>Library</OutputType>
@@ -94,7 +94,6 @@
     <Compile Include="XmlTvImporter.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="XmlTvSetup.cs">
-      <SubType>UserControl</SubType>
     </Compile>
     <Compile Include="XmlTvSetup.designer.cs">
       <DependentUpon>XmlTvSetup.cs</DependentUpon>
Index: TvEngine3/TVLibrary/SetupTv/58_upgrade_mysql_database.sql
===================================================================
--- TvEngine3/TVLibrary/SetupTv/58_upgrade_mysql_database.sql	(revision 0)
+++ TvEngine3/TVLibrary/SetupTv/58_upgrade_mysql_database.sql	(revision 0)
@@ -0,0 +1,12 @@
+USE %TvLibrary%;
+
+ALTER TABLE "program"
+	ADD COLUMN "seriesId" INT;
+	
+ALTER TABLE "program"
+	ADD COLUMN "seriesTermination" TINYINT;
+
+ALTER TABLE "schedule"
+	ADD COLUMN "seriesId" INT;
+	
+UPDATE Version SET versionNumber=58;
Index: TvEngine3/TVLibrary/SetupTv/58_upgrade_sqlserver_database.sql
===================================================================
--- TvEngine3/TVLibrary/SetupTv/58_upgrade_sqlserver_database.sql	(revision 0)
+++ TvEngine3/TVLibrary/SetupTv/58_upgrade_sqlserver_database.sql	(revision 0)
@@ -0,0 +1,17 @@
+use %TvLibrary%
+GO
+ 
+ALTER TABLE program
+	ADD seriesId INT
+GO
+ 
+ALTER TABLE program
+	ADD seriesTermination TINYINT
+GO
+ 
+ALTER TABLE schedule
+	ADD seriesId INT
+GO
+
+UPDATE Version SET versionNumber=58
+GO
Index: TvEngine3/TVLibrary/SetupTv/Sections/Dialogs/SkyDefaultTransponderSetup.cs
===================================================================
--- TvEngine3/TVLibrary/SetupTv/Sections/Dialogs/SkyDefaultTransponderSetup.cs	(revision 0)
+++ TvEngine3/TVLibrary/SetupTv/Sections/Dialogs/SkyDefaultTransponderSetup.cs	(revision 0)
@@ -0,0 +1,140 @@
+﻿using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using TvDatabase;
+using TvLibrary.Implementations;
+using TvLibrary.Implementations.Helper.Providers;
+
+namespace SetupTv.Sections.Dialogs
+{
+  public partial class SkyDefaultTransponderSetup : Form
+  {
+    /// <summary>
+    /// Sky country
+    /// </summary>
+    public enum eSkyCounntry
+    {
+      UK,
+      Italy,
+      Australia,
+    }
+
+    /// <summary>
+    /// Sky country
+    /// </summary>
+    private readonly eSkyCounntry _skyCountry;
+
+    /// <summary>
+    /// Cstr
+    /// </summary>
+    /// <param name="country"></param>
+    public SkyDefaultTransponderSetup(eSkyCounntry country)
+    {
+      _skyCountry = country;
+
+      InitializeComponent();
+
+      LoadValues();
+
+      tbFrequency.Select(tbFrequency.Text.Length, tbFrequency.Text.Length);
+    }
+
+    /// <summary>
+    /// Loads the values into the fields
+    /// </summary>
+    private void LoadValues()
+    {
+      if (_skyCountry == eSkyCounntry.UK)
+      {
+        tbFrequency.Text = SkyUK.Instance.DefaultTransponderFrequency.ToString();
+        tbSymbolRate.Text = SkyUK.Instance.DefaultTransponderSymbolRate.ToString();
+        tbNetworkId.Text = SkyUK.Instance.NetworkId.ToString("X");
+
+        cbPolarisation.SelectedItem = SkyUK.Instance.DefaultTransponderPolarisationString;
+        cbFEC.SelectedItem = SkyUK.Instance.DefaultTransponderInnerFECString;
+      }
+
+      if (_skyCountry == eSkyCounntry.Italy)
+      {
+        tbFrequency.Text = SkyItaly.Instance.DefaultTransponderFrequency.ToString();
+        tbSymbolRate.Text = SkyItaly.Instance.DefaultTransponderSymbolRate.ToString();
+        tbNetworkId.Text = SkyItaly.Instance.NetworkId.ToString("X");
+
+        cbPolarisation.SelectedItem = SkyItaly.Instance.DefaultTransponderPolarisationString;
+        cbFEC.SelectedItem = SkyItaly.Instance.DefaultTransponderInnerFECString;
+      }
+    }
+    /// <summary>
+    /// Fired when the save button is clicked
+    /// </summary>
+    /// <param name="sender"></param>
+    /// <param name="e"></param>
+    private void btSave_Click(object sender, EventArgs e)
+    {
+      string frequencyString = tbFrequency.Text;
+      int frequency = 0;
+
+      if (!int.TryParse(frequencyString, out frequency))
+      {
+        MessageBox.Show("Please enter a valid number for frequency", "Validation");
+        return;
+      }
+
+      string symbolRateString = tbSymbolRate.Text;
+      int symbolRate = 0;
+
+      if (!int.TryParse(symbolRateString, out symbolRate))
+      {
+        MessageBox.Show("Please enter a valid number for symbol rate", "Validation");
+        return;
+      }
+
+      string networkIdString = tbNetworkId.Text;
+      int networkId = 0;
+
+      if (!int.TryParse(networkIdString, System.Globalization.NumberStyles.HexNumber, null, out networkId))
+      {
+        MessageBox.Show("Please enter a valid number for network id", "Validation");
+        return;
+      }
+
+      if (_skyCountry == eSkyCounntry.UK)
+      {
+        SkyUK.Instance.DefaultTransponderFrequency = frequency;
+        SkyUK.Instance.DefaultTransponderPolarisationString = cbPolarisation.SelectedItem as string;
+        SkyUK.Instance.DefaultTransponderSymbolRate = symbolRate;
+        SkyUK.Instance.DefaultTransponderInnerFECString = cbFEC.SelectedItem as string;
+        SkyUK.Instance.NetworkId = networkId;
+      }
+
+      if (_skyCountry == eSkyCounntry.Italy)
+      {
+        SkyItaly.Instance.DefaultTransponderFrequency = frequency;
+        SkyItaly.Instance.DefaultTransponderPolarisationString = cbPolarisation.SelectedItem as string;
+        SkyItaly.Instance.DefaultTransponderSymbolRate = symbolRate;
+        SkyItaly.Instance.DefaultTransponderInnerFECString = cbFEC.SelectedItem as string;
+        SkyItaly.Instance.NetworkId = networkId;
+      }
+
+      DialogResult = DialogResult.OK;
+
+      Close();
+    }
+
+    /// <summary>
+    /// Fired when the cancel button is clicked
+    /// </summary>
+    /// <param name="sender"></param>
+    /// <param name="e"></param>
+    private void btCancel_Click(object sender, EventArgs e)
+    {
+      DialogResult = DialogResult.Cancel;
+
+      Close();
+    }
+  }
+}
Index: TvEngine3/TVLibrary/SetupTv/Sections/Dialogs/SkyDefaultTransponderSetup.Designer.cs
===================================================================
--- TvEngine3/TVLibrary/SetupTv/Sections/Dialogs/SkyDefaultTransponderSetup.Designer.cs	(revision 0)
+++ TvEngine3/TVLibrary/SetupTv/Sections/Dialogs/SkyDefaultTransponderSetup.Designer.cs	(revision 0)
@@ -0,0 +1,214 @@
+﻿namespace SetupTv.Sections.Dialogs
+{
+  partial class SkyDefaultTransponderSetup
+  {
+    /// <summary>
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary>
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing)
+    {
+      if (disposing && (components != null))
+      {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Windows Form Designer generated code
+
+    /// <summary>
+    /// Required method for Designer support - do not modify
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent()
+    {
+      this.lbFrequency = new MediaPortal.UserInterface.Controls.MPLabel();
+      this.tbFrequency = new MediaPortal.UserInterface.Controls.MPTextBox();
+      this.cbPolarisation = new MediaPortal.UserInterface.Controls.MPComboBox();
+      this.tbSymbolRate = new MediaPortal.UserInterface.Controls.MPTextBox();
+      this.tbNetworkId = new MediaPortal.UserInterface.Controls.MPTextBox();
+      this.cbFEC = new MediaPortal.UserInterface.Controls.MPComboBox();
+      this.lbPolarisation = new MediaPortal.UserInterface.Controls.MPLabel();
+      this.lbSymbolRate = new MediaPortal.UserInterface.Controls.MPLabel();
+      this.lbFEC = new MediaPortal.UserInterface.Controls.MPLabel();
+      this.lbNetworkId = new MediaPortal.UserInterface.Controls.MPLabel();
+      this.btSave = new MediaPortal.UserInterface.Controls.MPButton();
+      this.btCancel = new MediaPortal.UserInterface.Controls.MPButton();
+      this.SuspendLayout();
+      // 
+      // lbFrequency
+      // 
+      this.lbFrequency.AutoSize = true;
+      this.lbFrequency.Location = new System.Drawing.Point(17, 15);
+      this.lbFrequency.Name = "lbFrequency";
+      this.lbFrequency.Size = new System.Drawing.Size(83, 13);
+      this.lbFrequency.TabIndex = 0;
+      this.lbFrequency.Text = "Frequency (khz)";
+      // 
+      // tbFrequency
+      // 
+      this.tbFrequency.Location = new System.Drawing.Point(106, 12);
+      this.tbFrequency.Name = "tbFrequency";
+      this.tbFrequency.Size = new System.Drawing.Size(100, 20);
+      this.tbFrequency.TabIndex = 1;
+      // 
+      // cbPolarisation
+      // 
+      this.cbPolarisation.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.cbPolarisation.FormattingEnabled = true;
+      this.cbPolarisation.Items.AddRange(new object[] {
+            "Horizontal",
+            "Vertical",
+            "Circular Left",
+            "Circular Right"});
+      this.cbPolarisation.Location = new System.Drawing.Point(106, 38);
+      this.cbPolarisation.Name = "cbPolarisation";
+      this.cbPolarisation.Size = new System.Drawing.Size(100, 21);
+      this.cbPolarisation.TabIndex = 2;
+      // 
+      // tbSymbolRate
+      // 
+      this.tbSymbolRate.Location = new System.Drawing.Point(106, 65);
+      this.tbSymbolRate.Name = "tbSymbolRate";
+      this.tbSymbolRate.Size = new System.Drawing.Size(100, 20);
+      this.tbSymbolRate.TabIndex = 3;
+      // 
+      // tbNetworkId
+      // 
+      this.tbNetworkId.Location = new System.Drawing.Point(106, 118);
+      this.tbNetworkId.Name = "tbNetworkId";
+      this.tbNetworkId.Size = new System.Drawing.Size(100, 20);
+      this.tbNetworkId.TabIndex = 4;
+      // 
+      // cbFEC
+      // 
+      this.cbFEC.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.cbFEC.FormattingEnabled = true;
+      this.cbFEC.Items.AddRange(new object[] {
+            "1/2",
+            "1/3",
+            "1/4",
+            "2/3",
+            "2/5",
+            "3/4",
+            "3/5",
+            "4/5",
+            "5/11",
+            "5/6",
+            "7/8",
+            "8/9",
+            "9/10"});
+      this.cbFEC.Location = new System.Drawing.Point(106, 91);
+      this.cbFEC.Name = "cbFEC";
+      this.cbFEC.Size = new System.Drawing.Size(100, 21);
+      this.cbFEC.TabIndex = 5;
+      // 
+      // lbPolarisation
+      // 
+      this.lbPolarisation.AutoSize = true;
+      this.lbPolarisation.Location = new System.Drawing.Point(17, 41);
+      this.lbPolarisation.Name = "lbPolarisation";
+      this.lbPolarisation.Size = new System.Drawing.Size(61, 13);
+      this.lbPolarisation.TabIndex = 6;
+      this.lbPolarisation.Text = "Polarisation";
+      // 
+      // lbSymbolRate
+      // 
+      this.lbSymbolRate.AutoSize = true;
+      this.lbSymbolRate.Location = new System.Drawing.Point(17, 68);
+      this.lbSymbolRate.Name = "lbSymbolRate";
+      this.lbSymbolRate.Size = new System.Drawing.Size(62, 13);
+      this.lbSymbolRate.TabIndex = 7;
+      this.lbSymbolRate.Text = "Symbol rate";
+      // 
+      // lbFEC
+      // 
+      this.lbFEC.AutoSize = true;
+      this.lbFEC.Location = new System.Drawing.Point(17, 94);
+      this.lbFEC.Name = "lbFEC";
+      this.lbFEC.Size = new System.Drawing.Size(27, 13);
+      this.lbFEC.TabIndex = 8;
+      this.lbFEC.Text = "FEC";
+      // 
+      // lbNetworkId
+      // 
+      this.lbNetworkId.AutoSize = true;
+      this.lbNetworkId.Location = new System.Drawing.Point(18, 121);
+      this.lbNetworkId.Name = "lbNetworkId";
+      this.lbNetworkId.Size = new System.Drawing.Size(81, 13);
+      this.lbNetworkId.TabIndex = 9;
+      this.lbNetworkId.Text = "Network ID (0x)";
+      // 
+      // btSave
+      // 
+      this.btSave.Location = new System.Drawing.Point(37, 163);
+      this.btSave.Name = "btSave";
+      this.btSave.Size = new System.Drawing.Size(75, 25);
+      this.btSave.TabIndex = 10;
+      this.btSave.Text = "Save";
+      this.btSave.UseVisualStyleBackColor = true;
+      this.btSave.Click += new System.EventHandler(this.btSave_Click);
+      // 
+      // btCancel
+      // 
+      this.btCancel.Location = new System.Drawing.Point(118, 163);
+      this.btCancel.Name = "btCancel";
+      this.btCancel.Size = new System.Drawing.Size(75, 25);
+      this.btCancel.TabIndex = 11;
+      this.btCancel.Text = "Cancel";
+      this.btCancel.UseVisualStyleBackColor = true;
+      this.btCancel.Click += new System.EventHandler(this.btCancel_Click);
+      // 
+      // SkyDefaultTransponderSetup
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.ClientSize = new System.Drawing.Size(231, 200);
+      this.Controls.Add(this.btCancel);
+      this.Controls.Add(this.btSave);
+      this.Controls.Add(this.lbNetworkId);
+      this.Controls.Add(this.lbFEC);
+      this.Controls.Add(this.lbSymbolRate);
+      this.Controls.Add(this.lbPolarisation);
+      this.Controls.Add(this.cbFEC);
+      this.Controls.Add(this.tbNetworkId);
+      this.Controls.Add(this.tbSymbolRate);
+      this.Controls.Add(this.cbPolarisation);
+      this.Controls.Add(this.tbFrequency);
+      this.Controls.Add(this.lbFrequency);
+      this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
+      this.MaximizeBox = false;
+      this.MinimizeBox = false;
+      this.Name = "SkyDefaultTransponderSetup";
+      this.ShowIcon = false;
+      this.ShowInTaskbar = false;
+      this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
+      this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+      this.Text = "Default transponder setup";
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private MediaPortal.UserInterface.Controls.MPLabel lbFrequency;
+    private MediaPortal.UserInterface.Controls.MPTextBox tbFrequency;
+    private MediaPortal.UserInterface.Controls.MPComboBox cbPolarisation;
+    private MediaPortal.UserInterface.Controls.MPTextBox tbSymbolRate;
+    private MediaPortal.UserInterface.Controls.MPTextBox tbNetworkId;
+    private MediaPortal.UserInterface.Controls.MPComboBox cbFEC;
+    private MediaPortal.UserInterface.Controls.MPLabel lbPolarisation;
+    private MediaPortal.UserInterface.Controls.MPLabel lbSymbolRate;
+    private MediaPortal.UserInterface.Controls.MPLabel lbFEC;
+    private MediaPortal.UserInterface.Controls.MPLabel lbNetworkId;
+    private MediaPortal.UserInterface.Controls.MPButton btSave;
+    private MediaPortal.UserInterface.Controls.MPButton btCancel;
+  }
+}
Index: TvEngine3/TVLibrary/SetupTv/Sections/Dialogs/SkyDefaultTransponderSetup.resx
===================================================================
--- TvEngine3/TVLibrary/SetupTv/Sections/Dialogs/SkyDefaultTransponderSetup.resx	(revision 0)
+++ TvEngine3/TVLibrary/SetupTv/Sections/Dialogs/SkyDefaultTransponderSetup.resx	(revision 0)
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
Index: TvEngine3/TVLibrary/SetupTv/Sections/ImportExport.cs
===================================================================
--- TvEngine3/TVLibrary/SetupTv/Sections/ImportExport.cs	(revision 27484)
+++ TvEngine3/TVLibrary/SetupTv/Sections/ImportExport.cs	(working copy)
@@ -219,6 +219,7 @@
           AddAttribute(nodeSchedule, "RecommendedCard", schedule.RecommendedCard);
           AddAttribute(nodeSchedule, "ScheduleType", schedule.ScheduleType);
           AddAttribute(nodeSchedule, "Series", schedule.Series);
+          AddAttribute(nodeSchedule, "SeriesId", schedule.SeriesId);
           nodeSchedules.AppendChild(nodeSchedule);
         }
         rootElement.AppendChild(nodeSchedules);
@@ -720,6 +721,7 @@
               schedule.RecommendedCard = Int32.Parse(nodeSchedule.Attributes["RecommendedCard"].Value);
               schedule.ScheduleType = Int32.Parse(nodeSchedule.Attributes["ScheduleType"].Value);
               schedule.Series = (GetNodeAttribute(nodeSchedule, "Series", "False") == "True");
+              schedule.SeriesId = Int32.Parse((nodeSchedule.Attributes["SeriesId"] != null ? nodeSchedule.Attributes["SeriesId"].Value : "0"));
               if (idChannel > -1)
               {
                 schedule.Persist();
Index: C:/Projects/Clean Working Copies/MediaPortal trunk/TvEngine3/TVLibrary/SetupTv/Sections/ProviderEpgGrabber.cs
===================================================================
--- C:/Projects/Clean Working Copies/MediaPortal trunk/TvEngine3/TVLibrary/SetupTv/Sections/ProviderEpgGrabber.cs	(revision 0)
+++ C:/Projects/Clean Working Copies/MediaPortal trunk/TvEngine3/TVLibrary/SetupTv/Sections/ProviderEpgGrabber.cs	(revision 0)
@@ -0,0 +1,151 @@
+#region Copyright (C) 2005-2010 Team MediaPortal
+
+// Copyright (C) 2005-2010 Team MediaPortal
+// http://www.team-mediaportal.com
+// 
+// MediaPortal is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+// 
+// MediaPortal is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with MediaPortal. If not, see <http://www.gnu.org/licenses/>.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Windows.Forms;
+using TvControl;
+using Gentle.Framework;
+using TvDatabase;
+using TvLibrary.Log;
+using TvLibrary.Interfaces;
+using MediaPortal.UserInterface.Controls;
+using SetupTv.Sections.Dialogs;
+using TvLibrary.Implementations;
+using TvLibrary.Implementations.Helper.Providers;
+
+namespace SetupTv.Sections
+{
+  public partial class ProviderEPGs : SectionSettings
+  {
+
+    public ProviderEPGs()
+      : base("Provider Epgs") 
+    {
+        InitializeComponent();
+    }
+
+    public override void LoadSettings()
+    {
+      LoadSkyUKSettings();
+      LoadSkyItalySettings();
+
+      base.LoadSettings();
+    }
+
+    /// <summary>
+    /// Loads the settings fo Sky UK
+    /// </summary>
+    private void LoadSkyUKSettings()
+    {
+      lbSkyUKFrequencyValue.Text = SkyUK.Instance.DefaultTransponderFrequency.ToString();
+      lbSkyUKPolarisationValue.Text = SkyUK.Instance.DefaultTransponderPolarisationString;
+      lbSkyUKSymbolRateValue.Text = SkyUK.Instance.DefaultTransponderSymbolRate.ToString();
+      lbSkyUKFECValue.Text = SkyUK.Instance.DefaultTransponderInnerFECString;
+
+      lbSkyUKNetworkIdValue.Text = "0x" + SkyUK.Instance.NetworkId.ToString("X");
+
+      cbGrabSkyUKEpg.Checked = SkyUK.Instance.EPGGrabbingEnabled;
+    }
+
+    /// <summary>
+    /// Loads the settings for Sky Italy
+    /// </summary>
+    private void LoadSkyItalySettings()
+    {
+      lbSkyItalyFrequencyValue.Text = SkyItaly.Instance.DefaultTransponderFrequency.ToString();
+      lbSkyItalyPolarisationValue.Text = SkyItaly.Instance.DefaultTransponderPolarisationString;
+      lbSkyItalySymbolRateValue.Text = SkyItaly.Instance.DefaultTransponderSymbolRate.ToString();
+      lbSkyItalyFECValue.Text = SkyItaly.Instance.DefaultTransponderInnerFECString;
+
+      lbSkyItalyNetworkIdValue.Text = "0x" + SkyItaly.Instance.NetworkId.ToString("X");
+
+      cbGrabSkyItalyEpg.Checked = SkyItaly.Instance.EPGGrabbingEnabled;
+    }
+
+    public override void SaveSettings()
+    {
+      SkyUK.Instance.EPGGrabbingEnabled = cbGrabSkyUKEpg.Checked;
+      SkyItaly.Instance.EPGGrabbingEnabled = cbGrabSkyItalyEpg.Checked;
+
+      base.SaveSettings();
+    }
+
+    /// <summary>
+    /// Fired when the edit default sky uk transponder button is clicked
+    /// </summary>
+    /// <param name="sender"></param>
+    /// <param name="e"></param>
+    private void btEditDefaultSkyUKTransponder_Click(object sender, EventArgs e)
+    {
+      SkyDefaultTransponderSetup defaultTransponderSetup = new SkyDefaultTransponderSetup(SkyDefaultTransponderSetup.eSkyCounntry.UK);
+      DialogResult result = defaultTransponderSetup.ShowDialog();
+
+      //  If ok was clicked, reload the sky uk settings
+      if (result == DialogResult.OK)
+        LoadSkyUKSettings();
+    }
+
+    /// <summary>
+    /// Fired when the reset sky uk default transponder settings button is clicked
+    /// </summary>
+    /// <param name="sender"></param>
+    /// <param name="e"></param>
+    private void btResetDefaultSkyUKTransponder_Click(object sender, EventArgs e)
+    {
+      if (MessageBox.Show("This will reset the parameters for the default transponder.\r\n\r\nAre you sure?", "Confirm", MessageBoxButtons.YesNo) == DialogResult.Yes)
+      {
+        SkyUK.Instance.ResetDefaultTransponderParameters();
+        LoadSkyUKSettings();
+      }
+    }
+
+    /// <summary>
+    /// Fired when the edit Sky Italy default transponder parameters button is clicked
+    /// </summary>
+    /// <param name="sender"></param>
+    /// <param name="e"></param>
+    private void btEditSkyItalyDefaultTransponder_Click(object sender, EventArgs e)
+    {
+      SkyDefaultTransponderSetup defaultTransponderSetup = new SkyDefaultTransponderSetup(SkyDefaultTransponderSetup.eSkyCounntry.Italy);
+      DialogResult result = defaultTransponderSetup.ShowDialog();
+
+      //  If ok was clicked, reload the sky uk settings
+      if (result == DialogResult.OK)
+        LoadSkyItalySettings();
+    }
+
+    /// <summary>
+    /// Fired when the reset Sky Italy default transponder parameters button is clicked
+    /// </summary>
+    /// <param name="sender"></param>
+    /// <param name="e"></param>
+    private void btResetSkyItalyDefaultTransponder_Click(object sender, EventArgs e)
+    {
+      if (MessageBox.Show("This will reset the parameters for the default transponder.\r\n\r\nAre you sure?", "Confirm", MessageBoxButtons.YesNo) == DialogResult.Yes)
+      {
+        SkyItaly.Instance.ResetDefaultTransponderParameters();
+        LoadSkyItalySettings();
+      }
+    }
+
+
+  }
+}
Index: TvEngine3/TVLibrary/SetupTv/Sections/ProviderEpgGrabber.Designer.cs
===================================================================
--- TvEngine3/TVLibrary/SetupTv/Sections/ProviderEpgGrabber.Designer.cs	(revision 0)
+++ TvEngine3/TVLibrary/SetupTv/Sections/ProviderEpgGrabber.Designer.cs	(revision 0)
@@ -0,0 +1,550 @@
+namespace SetupTv.Sections
+{
+  partial class ProviderEPGs
+  {
+    /// <summary>
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary>
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing)
+    {
+      if (disposing && (components != null))
+      {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Windows Form Designer generated code
+
+    /// <summary>
+    /// Required method for Designer support - do not modify
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent()
+    {
+      this.tabControl1 = new System.Windows.Forms.TabControl();
+      this.tabPage1 = new System.Windows.Forms.TabPage();
+      this.cbGrabSkyUKEpg = new MediaPortal.UserInterface.Controls.MPCheckBox();
+      this.btResetDefaultSkyUKTransponder = new System.Windows.Forms.Button();
+      this.gbSkyUKDefaultTransponder = new System.Windows.Forms.GroupBox();
+      this.lbSkyUKNetworkIdValue = new System.Windows.Forms.Label();
+      this.lbSkyUKFrequency = new System.Windows.Forms.Label();
+      this.lbSkyUKFrequencyValue = new System.Windows.Forms.Label();
+      this.lbSkyUKFECValue = new System.Windows.Forms.Label();
+      this.lbSkyUKPolarisation = new System.Windows.Forms.Label();
+      this.lbSkyUKNetworkId = new System.Windows.Forms.Label();
+      this.lbSkyUKPolarisationValue = new System.Windows.Forms.Label();
+      this.lbSkyUKSymbolRateValue = new System.Windows.Forms.Label();
+      this.lbSkyUKSymbolRate = new System.Windows.Forms.Label();
+      this.lbSkyUKFEC = new System.Windows.Forms.Label();
+      this.btEditDefaultSkyUKTransponder = new System.Windows.Forms.Button();
+      this.mpLabelChannelCount = new MediaPortal.UserInterface.Controls.MPLabel();
+      this.tabPage2 = new System.Windows.Forms.TabPage();
+      this.cbGrabSkyItalyEpg = new MediaPortal.UserInterface.Controls.MPCheckBox();
+      this.btResetSkyItalyDefaultTransponder = new System.Windows.Forms.Button();
+      this.gbSkyItalyDefaultTransponder = new System.Windows.Forms.GroupBox();
+      this.lbSkyItalyNetworkIdValue = new System.Windows.Forms.Label();
+      this.lbSkyItalyFrequency = new System.Windows.Forms.Label();
+      this.lbSkyItalyFrequencyValue = new System.Windows.Forms.Label();
+      this.lbSkyItalyFECValue = new System.Windows.Forms.Label();
+      this.lbSkyItalyPolarisation = new System.Windows.Forms.Label();
+      this.lbSkyItalyNetworkId = new System.Windows.Forms.Label();
+      this.lbSkyItalyPolarisationValue = new System.Windows.Forms.Label();
+      this.lbSkyItalySymbolRateValue = new System.Windows.Forms.Label();
+      this.lbSkyItalySymbolRate = new System.Windows.Forms.Label();
+      this.lbSkyItalyFEC = new System.Windows.Forms.Label();
+      this.btEditSkyItalyDefaultTransponder = new System.Windows.Forms.Button();
+      this.label1 = new System.Windows.Forms.Label();
+      this.label2 = new System.Windows.Forms.Label();
+      this.label3 = new System.Windows.Forms.Label();
+      this.label4 = new System.Windows.Forms.Label();
+      this.label5 = new System.Windows.Forms.Label();
+      this.label6 = new System.Windows.Forms.Label();
+      this.label7 = new System.Windows.Forms.Label();
+      this.label8 = new System.Windows.Forms.Label();
+      this.label9 = new System.Windows.Forms.Label();
+      this.label10 = new System.Windows.Forms.Label();
+      this.tabControl1.SuspendLayout();
+      this.tabPage1.SuspendLayout();
+      this.gbSkyUKDefaultTransponder.SuspendLayout();
+      this.tabPage2.SuspendLayout();
+      this.gbSkyItalyDefaultTransponder.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // tabControl1
+      // 
+      this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                  | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.tabControl1.Controls.Add(this.tabPage1);
+      this.tabControl1.Controls.Add(this.tabPage2);
+      this.tabControl1.Location = new System.Drawing.Point(3, 3);
+      this.tabControl1.Name = "tabControl1";
+      this.tabControl1.SelectedIndex = 0;
+      this.tabControl1.Size = new System.Drawing.Size(485, 431);
+      this.tabControl1.TabIndex = 10;
+      // 
+      // tabPage1
+      // 
+      this.tabPage1.Controls.Add(this.cbGrabSkyUKEpg);
+      this.tabPage1.Controls.Add(this.btResetDefaultSkyUKTransponder);
+      this.tabPage1.Controls.Add(this.gbSkyUKDefaultTransponder);
+      this.tabPage1.Controls.Add(this.btEditDefaultSkyUKTransponder);
+      this.tabPage1.Controls.Add(this.mpLabelChannelCount);
+      this.tabPage1.Location = new System.Drawing.Point(4, 22);
+      this.tabPage1.Name = "tabPage1";
+      this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
+      this.tabPage1.Size = new System.Drawing.Size(477, 405);
+      this.tabPage1.TabIndex = 0;
+      this.tabPage1.Text = "Sky UK";
+      this.tabPage1.UseVisualStyleBackColor = true;
+      // 
+      // cbGrabSkyUKEpg
+      // 
+      this.cbGrabSkyUKEpg.AutoSize = true;
+      this.cbGrabSkyUKEpg.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+      this.cbGrabSkyUKEpg.Location = new System.Drawing.Point(19, 25);
+      this.cbGrabSkyUKEpg.Name = "cbGrabSkyUKEpg";
+      this.cbGrabSkyUKEpg.Size = new System.Drawing.Size(111, 17);
+      this.cbGrabSkyUKEpg.TabIndex = 24;
+      this.cbGrabSkyUKEpg.Text = "Grab Sky UK EPG";
+      this.cbGrabSkyUKEpg.UseVisualStyleBackColor = true;
+      // 
+      // btResetDefaultSkyUKTransponder
+      // 
+      this.btResetDefaultSkyUKTransponder.Location = new System.Drawing.Point(366, 68);
+      this.btResetDefaultSkyUKTransponder.Name = "btResetDefaultSkyUKTransponder";
+      this.btResetDefaultSkyUKTransponder.Size = new System.Drawing.Size(50, 24);
+      this.btResetDefaultSkyUKTransponder.TabIndex = 23;
+      this.btResetDefaultSkyUKTransponder.Text = "Reset";
+      this.btResetDefaultSkyUKTransponder.UseVisualStyleBackColor = true;
+      this.btResetDefaultSkyUKTransponder.Click += new System.EventHandler(this.btResetDefaultSkyUKTransponder_Click);
+      // 
+      // gbSkyUKDefaultTransponder
+      // 
+      this.gbSkyUKDefaultTransponder.Controls.Add(this.lbSkyUKNetworkIdValue);
+      this.gbSkyUKDefaultTransponder.Controls.Add(this.lbSkyUKFrequency);
+      this.gbSkyUKDefaultTransponder.Controls.Add(this.lbSkyUKFrequencyValue);
+      this.gbSkyUKDefaultTransponder.Controls.Add(this.lbSkyUKFECValue);
+      this.gbSkyUKDefaultTransponder.Controls.Add(this.lbSkyUKPolarisation);
+      this.gbSkyUKDefaultTransponder.Controls.Add(this.lbSkyUKNetworkId);
+      this.gbSkyUKDefaultTransponder.Controls.Add(this.lbSkyUKPolarisationValue);
+      this.gbSkyUKDefaultTransponder.Controls.Add(this.lbSkyUKSymbolRateValue);
+      this.gbSkyUKDefaultTransponder.Controls.Add(this.lbSkyUKSymbolRate);
+      this.gbSkyUKDefaultTransponder.Controls.Add(this.lbSkyUKFEC);
+      this.gbSkyUKDefaultTransponder.Location = new System.Drawing.Point(157, 25);
+      this.gbSkyUKDefaultTransponder.Name = "gbSkyUKDefaultTransponder";
+      this.gbSkyUKDefaultTransponder.Size = new System.Drawing.Size(194, 148);
+      this.gbSkyUKDefaultTransponder.TabIndex = 21;
+      this.gbSkyUKDefaultTransponder.TabStop = false;
+      this.gbSkyUKDefaultTransponder.Text = "Default Transponder";
+      // 
+      // lbSkyUKNetworkIdValue
+      // 
+      this.lbSkyUKNetworkIdValue.AutoSize = true;
+      this.lbSkyUKNetworkIdValue.Location = new System.Drawing.Point(109, 115);
+      this.lbSkyUKNetworkIdValue.Name = "lbSkyUKNetworkIdValue";
+      this.lbSkyUKNetworkIdValue.Size = new System.Drawing.Size(0, 13);
+      this.lbSkyUKNetworkIdValue.TabIndex = 10;
+      // 
+      // lbSkyUKFrequency
+      // 
+      this.lbSkyUKFrequency.AutoSize = true;
+      this.lbSkyUKFrequency.Location = new System.Drawing.Point(18, 27);
+      this.lbSkyUKFrequency.Name = "lbSkyUKFrequency";
+      this.lbSkyUKFrequency.Size = new System.Drawing.Size(83, 13);
+      this.lbSkyUKFrequency.TabIndex = 0;
+      this.lbSkyUKFrequency.Text = "Frequency (khz)";
+      // 
+      // lbSkyUKFrequencyValue
+      // 
+      this.lbSkyUKFrequencyValue.AutoSize = true;
+      this.lbSkyUKFrequencyValue.Location = new System.Drawing.Point(109, 27);
+      this.lbSkyUKFrequencyValue.Name = "lbSkyUKFrequencyValue";
+      this.lbSkyUKFrequencyValue.Size = new System.Drawing.Size(0, 13);
+      this.lbSkyUKFrequencyValue.TabIndex = 6;
+      // 
+      // lbSkyUKFECValue
+      // 
+      this.lbSkyUKFECValue.AutoSize = true;
+      this.lbSkyUKFECValue.Location = new System.Drawing.Point(109, 93);
+      this.lbSkyUKFECValue.Name = "lbSkyUKFECValue";
+      this.lbSkyUKFECValue.Size = new System.Drawing.Size(0, 13);
+      this.lbSkyUKFECValue.TabIndex = 9;
+      // 
+      // lbSkyUKPolarisation
+      // 
+      this.lbSkyUKPolarisation.AutoSize = true;
+      this.lbSkyUKPolarisation.Location = new System.Drawing.Point(18, 49);
+      this.lbSkyUKPolarisation.Name = "lbSkyUKPolarisation";
+      this.lbSkyUKPolarisation.Size = new System.Drawing.Size(61, 13);
+      this.lbSkyUKPolarisation.TabIndex = 1;
+      this.lbSkyUKPolarisation.Text = "Polarisation";
+      // 
+      // lbSkyUKNetworkId
+      // 
+      this.lbSkyUKNetworkId.AutoSize = true;
+      this.lbSkyUKNetworkId.Location = new System.Drawing.Point(18, 115);
+      this.lbSkyUKNetworkId.Name = "lbSkyUKNetworkId";
+      this.lbSkyUKNetworkId.Size = new System.Drawing.Size(61, 13);
+      this.lbSkyUKNetworkId.TabIndex = 5;
+      this.lbSkyUKNetworkId.Text = "Network ID";
+      // 
+      // lbSkyUKPolarisationValue
+      // 
+      this.lbSkyUKPolarisationValue.AutoSize = true;
+      this.lbSkyUKPolarisationValue.Location = new System.Drawing.Point(109, 49);
+      this.lbSkyUKPolarisationValue.Name = "lbSkyUKPolarisationValue";
+      this.lbSkyUKPolarisationValue.Size = new System.Drawing.Size(0, 13);
+      this.lbSkyUKPolarisationValue.TabIndex = 7;
+      // 
+      // lbSkyUKSymbolRateValue
+      // 
+      this.lbSkyUKSymbolRateValue.AutoSize = true;
+      this.lbSkyUKSymbolRateValue.Location = new System.Drawing.Point(109, 71);
+      this.lbSkyUKSymbolRateValue.Name = "lbSkyUKSymbolRateValue";
+      this.lbSkyUKSymbolRateValue.Size = new System.Drawing.Size(0, 13);
+      this.lbSkyUKSymbolRateValue.TabIndex = 8;
+      // 
+      // lbSkyUKSymbolRate
+      // 
+      this.lbSkyUKSymbolRate.AutoSize = true;
+      this.lbSkyUKSymbolRate.Location = new System.Drawing.Point(18, 71);
+      this.lbSkyUKSymbolRate.Name = "lbSkyUKSymbolRate";
+      this.lbSkyUKSymbolRate.Size = new System.Drawing.Size(67, 13);
+      this.lbSkyUKSymbolRate.TabIndex = 2;
+      this.lbSkyUKSymbolRate.Text = "Symbol Rate";
+      // 
+      // lbSkyUKFEC
+      // 
+      this.lbSkyUKFEC.AutoSize = true;
+      this.lbSkyUKFEC.Location = new System.Drawing.Point(18, 93);
+      this.lbSkyUKFEC.Name = "lbSkyUKFEC";
+      this.lbSkyUKFEC.Size = new System.Drawing.Size(27, 13);
+      this.lbSkyUKFEC.TabIndex = 4;
+      this.lbSkyUKFEC.Text = "FEC";
+      // 
+      // btEditDefaultSkyUKTransponder
+      // 
+      this.btEditDefaultSkyUKTransponder.Location = new System.Drawing.Point(366, 38);
+      this.btEditDefaultSkyUKTransponder.Name = "btEditDefaultSkyUKTransponder";
+      this.btEditDefaultSkyUKTransponder.Size = new System.Drawing.Size(50, 24);
+      this.btEditDefaultSkyUKTransponder.TabIndex = 22;
+      this.btEditDefaultSkyUKTransponder.Text = "Edit";
+      this.btEditDefaultSkyUKTransponder.UseVisualStyleBackColor = true;
+      this.btEditDefaultSkyUKTransponder.Click += new System.EventHandler(this.btEditDefaultSkyUKTransponder_Click);
+      // 
+      // mpLabelChannelCount
+      // 
+      this.mpLabelChannelCount.AutoSize = true;
+      this.mpLabelChannelCount.Location = new System.Drawing.Point(13, 14);
+      this.mpLabelChannelCount.Name = "mpLabelChannelCount";
+      this.mpLabelChannelCount.Size = new System.Drawing.Size(0, 13);
+      this.mpLabelChannelCount.TabIndex = 2;
+      // 
+      // tabPage2
+      // 
+      this.tabPage2.Controls.Add(this.cbGrabSkyItalyEpg);
+      this.tabPage2.Controls.Add(this.btResetSkyItalyDefaultTransponder);
+      this.tabPage2.Controls.Add(this.gbSkyItalyDefaultTransponder);
+      this.tabPage2.Controls.Add(this.btEditSkyItalyDefaultTransponder);
+      this.tabPage2.Location = new System.Drawing.Point(4, 22);
+      this.tabPage2.Name = "tabPage2";
+      this.tabPage2.Size = new System.Drawing.Size(477, 405);
+      this.tabPage2.TabIndex = 1;
+      this.tabPage2.Text = "Sky Italy";
+      this.tabPage2.UseVisualStyleBackColor = true;
+      // 
+      // cbGrabSkyItalyEpg
+      // 
+      this.cbGrabSkyItalyEpg.AutoSize = true;
+      this.cbGrabSkyItalyEpg.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
+      this.cbGrabSkyItalyEpg.Location = new System.Drawing.Point(19, 25);
+      this.cbGrabSkyItalyEpg.Name = "cbGrabSkyItalyEpg";
+      this.cbGrabSkyItalyEpg.Size = new System.Drawing.Size(115, 17);
+      this.cbGrabSkyItalyEpg.TabIndex = 29;
+      this.cbGrabSkyItalyEpg.Text = "Grab Sky Italy EPG";
+      this.cbGrabSkyItalyEpg.UseVisualStyleBackColor = true;
+      // 
+      // btResetSkyItalyDefaultTransponder
+      // 
+      this.btResetSkyItalyDefaultTransponder.Location = new System.Drawing.Point(366, 68);
+      this.btResetSkyItalyDefaultTransponder.Name = "btResetSkyItalyDefaultTransponder";
+      this.btResetSkyItalyDefaultTransponder.Size = new System.Drawing.Size(50, 24);
+      this.btResetSkyItalyDefaultTransponder.TabIndex = 28;
+      this.btResetSkyItalyDefaultTransponder.Text = "Reset";
+      this.btResetSkyItalyDefaultTransponder.UseVisualStyleBackColor = true;
+      this.btResetSkyItalyDefaultTransponder.Click += new System.EventHandler(this.btResetSkyItalyDefaultTransponder_Click);
+      // 
+      // gbSkyItalyDefaultTransponder
+      // 
+      this.gbSkyItalyDefaultTransponder.Controls.Add(this.lbSkyItalyNetworkIdValue);
+      this.gbSkyItalyDefaultTransponder.Controls.Add(this.lbSkyItalyFrequency);
+      this.gbSkyItalyDefaultTransponder.Controls.Add(this.lbSkyItalyFrequencyValue);
+      this.gbSkyItalyDefaultTransponder.Controls.Add(this.lbSkyItalyFECValue);
+      this.gbSkyItalyDefaultTransponder.Controls.Add(this.lbSkyItalyPolarisation);
+      this.gbSkyItalyDefaultTransponder.Controls.Add(this.lbSkyItalyNetworkId);
+      this.gbSkyItalyDefaultTransponder.Controls.Add(this.lbSkyItalyPolarisationValue);
+      this.gbSkyItalyDefaultTransponder.Controls.Add(this.lbSkyItalySymbolRateValue);
+      this.gbSkyItalyDefaultTransponder.Controls.Add(this.lbSkyItalySymbolRate);
+      this.gbSkyItalyDefaultTransponder.Controls.Add(this.lbSkyItalyFEC);
+      this.gbSkyItalyDefaultTransponder.Location = new System.Drawing.Point(157, 25);
+      this.gbSkyItalyDefaultTransponder.Name = "gbSkyItalyDefaultTransponder";
+      this.gbSkyItalyDefaultTransponder.Size = new System.Drawing.Size(194, 148);
+      this.gbSkyItalyDefaultTransponder.TabIndex = 26;
+      this.gbSkyItalyDefaultTransponder.TabStop = false;
+      this.gbSkyItalyDefaultTransponder.Text = "Default Transponder";
+      // 
+      // lbSkyItalyNetworkIdValue
+      // 
+      this.lbSkyItalyNetworkIdValue.AutoSize = true;
+      this.lbSkyItalyNetworkIdValue.Location = new System.Drawing.Point(109, 115);
+      this.lbSkyItalyNetworkIdValue.Name = "lbSkyItalyNetworkIdValue";
+      this.lbSkyItalyNetworkIdValue.Size = new System.Drawing.Size(0, 13);
+      this.lbSkyItalyNetworkIdValue.TabIndex = 10;
+      // 
+      // lbSkyItalyFrequency
+      // 
+      this.lbSkyItalyFrequency.AutoSize = true;
+      this.lbSkyItalyFrequency.Location = new System.Drawing.Point(18, 27);
+      this.lbSkyItalyFrequency.Name = "lbSkyItalyFrequency";
+      this.lbSkyItalyFrequency.Size = new System.Drawing.Size(83, 13);
+      this.lbSkyItalyFrequency.TabIndex = 0;
+      this.lbSkyItalyFrequency.Text = "Frequency (khz)";
+      // 
+      // lbSkyItalyFrequencyValue
+      // 
+      this.lbSkyItalyFrequencyValue.AutoSize = true;
+      this.lbSkyItalyFrequencyValue.Location = new System.Drawing.Point(109, 27);
+      this.lbSkyItalyFrequencyValue.Name = "lbSkyItalyFrequencyValue";
+      this.lbSkyItalyFrequencyValue.Size = new System.Drawing.Size(0, 13);
+      this.lbSkyItalyFrequencyValue.TabIndex = 6;
+      // 
+      // lbSkyItalyFECValue
+      // 
+      this.lbSkyItalyFECValue.AutoSize = true;
+      this.lbSkyItalyFECValue.Location = new System.Drawing.Point(109, 93);
+      this.lbSkyItalyFECValue.Name = "lbSkyItalyFECValue";
+      this.lbSkyItalyFECValue.Size = new System.Drawing.Size(0, 13);
+      this.lbSkyItalyFECValue.TabIndex = 9;
+      // 
+      // lbSkyItalyPolarisation
+      // 
+      this.lbSkyItalyPolarisation.AutoSize = true;
+      this.lbSkyItalyPolarisation.Location = new System.Drawing.Point(18, 49);
+      this.lbSkyItalyPolarisation.Name = "lbSkyItalyPolarisation";
+      this.lbSkyItalyPolarisation.Size = new System.Drawing.Size(61, 13);
+      this.lbSkyItalyPolarisation.TabIndex = 1;
+      this.lbSkyItalyPolarisation.Text = "Polarisation";
+      // 
+      // lbSkyItalyNetworkId
+      // 
+      this.lbSkyItalyNetworkId.AutoSize = true;
+      this.lbSkyItalyNetworkId.Location = new System.Drawing.Point(18, 115);
+      this.lbSkyItalyNetworkId.Name = "lbSkyItalyNetworkId";
+      this.lbSkyItalyNetworkId.Size = new System.Drawing.Size(61, 13);
+      this.lbSkyItalyNetworkId.TabIndex = 5;
+      this.lbSkyItalyNetworkId.Text = "Network ID";
+      // 
+      // lbSkyItalyPolarisationValue
+      // 
+      this.lbSkyItalyPolarisationValue.AutoSize = true;
+      this.lbSkyItalyPolarisationValue.Location = new System.Drawing.Point(109, 49);
+      this.lbSkyItalyPolarisationValue.Name = "lbSkyItalyPolarisationValue";
+      this.lbSkyItalyPolarisationValue.Size = new System.Drawing.Size(0, 13);
+      this.lbSkyItalyPolarisationValue.TabIndex = 7;
+      // 
+      // lbSkyItalySymbolRateValue
+      // 
+      this.lbSkyItalySymbolRateValue.AutoSize = true;
+      this.lbSkyItalySymbolRateValue.Location = new System.Drawing.Point(109, 71);
+      this.lbSkyItalySymbolRateValue.Name = "lbSkyItalySymbolRateValue";
+      this.lbSkyItalySymbolRateValue.Size = new System.Drawing.Size(0, 13);
+      this.lbSkyItalySymbolRateValue.TabIndex = 8;
+      // 
+      // lbSkyItalySymbolRate
+      // 
+      this.lbSkyItalySymbolRate.AutoSize = true;
+      this.lbSkyItalySymbolRate.Location = new System.Drawing.Point(18, 71);
+      this.lbSkyItalySymbolRate.Name = "lbSkyItalySymbolRate";
+      this.lbSkyItalySymbolRate.Size = new System.Drawing.Size(67, 13);
+      this.lbSkyItalySymbolRate.TabIndex = 2;
+      this.lbSkyItalySymbolRate.Text = "Symbol Rate";
+      // 
+      // lbSkyItalyFEC
+      // 
+      this.lbSkyItalyFEC.AutoSize = true;
+      this.lbSkyItalyFEC.Location = new System.Drawing.Point(18, 93);
+      this.lbSkyItalyFEC.Name = "lbSkyItalyFEC";
+      this.lbSkyItalyFEC.Size = new System.Drawing.Size(27, 13);
+      this.lbSkyItalyFEC.TabIndex = 4;
+      this.lbSkyItalyFEC.Text = "FEC";
+      // 
+      // btEditSkyItalyDefaultTransponder
+      // 
+      this.btEditSkyItalyDefaultTransponder.Location = new System.Drawing.Point(366, 38);
+      this.btEditSkyItalyDefaultTransponder.Name = "btEditSkyItalyDefaultTransponder";
+      this.btEditSkyItalyDefaultTransponder.Size = new System.Drawing.Size(50, 24);
+      this.btEditSkyItalyDefaultTransponder.TabIndex = 27;
+      this.btEditSkyItalyDefaultTransponder.Text = "Edit";
+      this.btEditSkyItalyDefaultTransponder.UseVisualStyleBackColor = true;
+      this.btEditSkyItalyDefaultTransponder.Click += new System.EventHandler(this.btEditSkyItalyDefaultTransponder_Click);
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(109, 115);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(0, 13);
+      this.label1.TabIndex = 10;
+      // 
+      // label2
+      // 
+      this.label2.AutoSize = true;
+      this.label2.Location = new System.Drawing.Point(18, 27);
+      this.label2.Name = "label2";
+      this.label2.Size = new System.Drawing.Size(83, 13);
+      this.label2.TabIndex = 0;
+      this.label2.Text = "Frequency (khz)";
+      // 
+      // label3
+      // 
+      this.label3.AutoSize = true;
+      this.label3.Location = new System.Drawing.Point(109, 27);
+      this.label3.Name = "label3";
+      this.label3.Size = new System.Drawing.Size(0, 13);
+      this.label3.TabIndex = 6;
+      // 
+      // label4
+      // 
+      this.label4.AutoSize = true;
+      this.label4.Location = new System.Drawing.Point(109, 93);
+      this.label4.Name = "label4";
+      this.label4.Size = new System.Drawing.Size(0, 13);
+      this.label4.TabIndex = 9;
+      // 
+      // label5
+      // 
+      this.label5.AutoSize = true;
+      this.label5.Location = new System.Drawing.Point(18, 49);
+      this.label5.Name = "label5";
+      this.label5.Size = new System.Drawing.Size(61, 13);
+      this.label5.TabIndex = 1;
+      this.label5.Text = "Polarisation";
+      // 
+      // label6
+      // 
+      this.label6.AutoSize = true;
+      this.label6.Location = new System.Drawing.Point(18, 115);
+      this.label6.Name = "label6";
+      this.label6.Size = new System.Drawing.Size(61, 13);
+      this.label6.TabIndex = 5;
+      this.label6.Text = "Network ID";
+      // 
+      // label7
+      // 
+      this.label7.AutoSize = true;
+      this.label7.Location = new System.Drawing.Point(109, 49);
+      this.label7.Name = "label7";
+      this.label7.Size = new System.Drawing.Size(0, 13);
+      this.label7.TabIndex = 7;
+      // 
+      // label8
+      // 
+      this.label8.AutoSize = true;
+      this.label8.Location = new System.Drawing.Point(109, 71);
+      this.label8.Name = "label8";
+      this.label8.Size = new System.Drawing.Size(0, 13);
+      this.label8.TabIndex = 8;
+      // 
+      // label9
+      // 
+      this.label9.AutoSize = true;
+      this.label9.Location = new System.Drawing.Point(18, 71);
+      this.label9.Name = "label9";
+      this.label9.Size = new System.Drawing.Size(67, 13);
+      this.label9.TabIndex = 2;
+      this.label9.Text = "Symbol Rate";
+      // 
+      // label10
+      // 
+      this.label10.AutoSize = true;
+      this.label10.Location = new System.Drawing.Point(18, 93);
+      this.label10.Name = "label10";
+      this.label10.Size = new System.Drawing.Size(27, 13);
+      this.label10.TabIndex = 4;
+      this.label10.Text = "FEC";
+      // 
+      // ProviderEPGs
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.tabControl1);
+      this.Name = "ProviderEPGs";
+      this.Size = new System.Drawing.Size(491, 437);
+      this.tabControl1.ResumeLayout(false);
+      this.tabPage1.ResumeLayout(false);
+      this.tabPage1.PerformLayout();
+      this.gbSkyUKDefaultTransponder.ResumeLayout(false);
+      this.gbSkyUKDefaultTransponder.PerformLayout();
+      this.tabPage2.ResumeLayout(false);
+      this.tabPage2.PerformLayout();
+      this.gbSkyItalyDefaultTransponder.ResumeLayout(false);
+      this.gbSkyItalyDefaultTransponder.PerformLayout();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.TabControl tabControl1;
+    private System.Windows.Forms.TabPage tabPage1;
+    private MediaPortal.UserInterface.Controls.MPLabel mpLabelChannelCount;
+    private MediaPortal.UserInterface.Controls.MPCheckBox cbGrabSkyUKEpg;
+    private System.Windows.Forms.Button btResetDefaultSkyUKTransponder;
+    private System.Windows.Forms.GroupBox gbSkyUKDefaultTransponder;
+    private System.Windows.Forms.Label lbSkyUKNetworkIdValue;
+    private System.Windows.Forms.Label lbSkyUKFrequency;
+    private System.Windows.Forms.Label lbSkyUKFrequencyValue;
+    private System.Windows.Forms.Label lbSkyUKFECValue;
+    private System.Windows.Forms.Label lbSkyUKPolarisation;
+    private System.Windows.Forms.Label lbSkyUKNetworkId;
+    private System.Windows.Forms.Label lbSkyUKPolarisationValue;
+    private System.Windows.Forms.Label lbSkyUKSymbolRateValue;
+    private System.Windows.Forms.Label lbSkyUKSymbolRate;
+    private System.Windows.Forms.Label lbSkyUKFEC;
+    private System.Windows.Forms.Button btEditDefaultSkyUKTransponder;
+    private System.Windows.Forms.TabPage tabPage2;
+    private MediaPortal.UserInterface.Controls.MPCheckBox cbGrabSkyItalyEpg;
+    private System.Windows.Forms.Button btResetSkyItalyDefaultTransponder;
+    private System.Windows.Forms.GroupBox gbSkyItalyDefaultTransponder;
+    private System.Windows.Forms.Label lbSkyItalyNetworkIdValue;
+    private System.Windows.Forms.Label lbSkyItalyFrequency;
+    private System.Windows.Forms.Label lbSkyItalyFrequencyValue;
+    private System.Windows.Forms.Label lbSkyItalyFECValue;
+    private System.Windows.Forms.Label lbSkyItalyPolarisation;
+    private System.Windows.Forms.Label lbSkyItalyNetworkId;
+    private System.Windows.Forms.Label lbSkyItalyPolarisationValue;
+    private System.Windows.Forms.Label lbSkyItalySymbolRateValue;
+    private System.Windows.Forms.Label lbSkyItalySymbolRate;
+    private System.Windows.Forms.Label lbSkyItalyFEC;
+    private System.Windows.Forms.Button btEditSkyItalyDefaultTransponder;
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.Label label2;
+    private System.Windows.Forms.Label label3;
+    private System.Windows.Forms.Label label4;
+    private System.Windows.Forms.Label label5;
+    private System.Windows.Forms.Label label6;
+    private System.Windows.Forms.Label label7;
+    private System.Windows.Forms.Label label8;
+    private System.Windows.Forms.Label label9;
+    private System.Windows.Forms.Label label10;
+
+  }
+}
Index: TvEngine3/TVLibrary/SetupTv/Sections/ProviderEpgGrabber.resx
===================================================================
--- TvEngine3/TVLibrary/SetupTv/Sections/ProviderEpgGrabber.resx	(revision 0)
+++ TvEngine3/TVLibrary/SetupTv/Sections/ProviderEpgGrabber.resx	(revision 0)
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
Index: TvEngine3/TVLibrary/SetupTv/Sections/TestService.cs
===================================================================
--- TvEngine3/TVLibrary/SetupTv/Sections/TestService.cs	(revision 27484)
+++ TvEngine3/TVLibrary/SetupTv/Sections/TestService.cs	(working copy)
@@ -28,6 +28,7 @@
 using TvLibrary.Log;
 using Gentle.Framework;
 using SetupControls;
+using TvLibrary.Implementations.Helper.Providers;
 
 namespace SetupTv.Sections
 {
@@ -536,6 +537,10 @@
         ch.Persist();
       }
 
+      //  Reset provider last grab time
+      SkyUK.Instance.LastEPGGrabTime = DateTime.MinValue;
+      SkyItaly.Instance.LastEPGGrabTime = DateTime.MinValue;
+
       RemoteControl.Instance.EpgGrabberEnabled = true;
       MessageBox.Show("EPG grabber will restart in a few seconds..");
     }
Index: TvEngine3/TVLibrary/SetupTv/SettingsForm.cs
===================================================================
--- TvEngine3/TVLibrary/SetupTv/SettingsForm.cs	(revision 27484)
+++ TvEngine3/TVLibrary/SetupTv/SettingsForm.cs	(working copy)
@@ -188,6 +188,7 @@
         AddSection(EpgSection);
         AddChildSection(EpgSection, new TvEpgGrabber());
         AddChildSection(EpgSection, new RadioEpgGrabber());
+        AddChildSection(EpgSection, new ProviderEPGs());
 
         AddSection(new ScanSettings());
         AddSection(new TvRecording());
Index: TvEngine3/TVLibrary/SetupTv/SetupTv.csproj
===================================================================
--- TvEngine3/TVLibrary/SetupTv/SetupTv.csproj	(revision 27484)
+++ TvEngine3/TVLibrary/SetupTv/SetupTv.csproj	(working copy)
@@ -2,7 +2,7 @@
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>9.0.30729</ProductVersion>
+    <ProductVersion>9.0.21022</ProductVersion>
     <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{FF9AAD68-BBE0-41F7-9183-F2B8474B9224}</ProjectGuid>
     <OutputType>WinExe</OutputType>
@@ -184,6 +184,18 @@
     </Compile>
     <Compile Include="ExtensionMethods.cs" />
     <Compile Include="HelpSystem.cs" />
+    <Compile Include="Sections\Dialogs\SkyDefaultTransponderSetup.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="Sections\Dialogs\SkyDefaultTransponderSetup.Designer.cs">
+      <DependentUpon>SkyDefaultTransponderSetup.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Sections\ProviderEpgGrabber.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Sections\ProviderEpgGrabber.Designer.cs">
+      <DependentUpon>ProviderEpgGrabber.cs</DependentUpon>
+    </Compile>
     <Compile Include="Sections\DebugOptions.cs">
       <SubType>UserControl</SubType>
     </Compile>
@@ -691,6 +703,14 @@
       <DependentUpon>FormWebStreamTuningDetail.cs</DependentUpon>
       <SubType>Designer</SubType>
     </EmbeddedResource>
+    <EmbeddedResource Include="Sections\Dialogs\SkyDefaultTransponderSetup.resx">
+      <DependentUpon>SkyDefaultTransponderSetup.cs</DependentUpon>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Sections\ProviderEpgGrabber.resx">
+      <DependentUpon>ProviderEpgGrabber.cs</DependentUpon>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
     <EmbeddedResource Include="Sections\DebugOptions.resx">
       <DependentUpon>DebugOptions.cs</DependentUpon>
       <SubType>Designer</SubType>
@@ -724,6 +744,8 @@
     <EmbeddedResource Include="56_upgrade_sqlserver_database.sql" />
     <EmbeddedResource Include="57_upgrade_mysql_database.sql" />
     <EmbeddedResource Include="57_upgrade_sqlserver_database.sql" />
+    <EmbeddedResource Include="58_upgrade_mysql_database.sql" />
+    <EmbeddedResource Include="58_upgrade_sqlserver_database.sql" />
     <None Include="images\icon.down.png" />
     <Content Include="images\icon.mpConfig.ico" />
     <Content Include="images\icon.radio_fta.png" />
Index: TvEngine3/TVLibrary/TVDatabase/Channel.cs
===================================================================
--- TvEngine3/TVLibrary/TVDatabase/Channel.cs	(revision 27484)
+++ TvEngine3/TVLibrary/TVDatabase/Channel.cs	(working copy)
@@ -637,8 +637,26 @@
     {
       //IFormatProvider mmddFormat = new CultureInfo(String.Empty, false);
       //DateTime startTime = DateTime.Now;
+      SqlBuilder sb = new SqlBuilder(StatementType.Select, typeof(Program));
+      sb.AddConstraint(Operator.Equals, "idChannel", IdChannel);
+      sb.AddConstraint(Operator.GreaterThan, "endTime", date);
+      sb.AddConstraint(Operator.LessThanOrEquals, "startTime", date);
+      sb.AddOrderByField(true, "startTime");
+      sb.SetRowLimit(1);
+      SqlStatement stmt = sb.GetStatement(true);
+      IList<Program> programs = ObjectFactory.GetCollection<Program>(stmt.Execute());
+      if (programs.Count == 0)
+      {
+        return null;
+      }
+      return programs[0];
+    }
+
+    public Program GetProgramAt(DateTime date, int seriesId)
+    {
       SqlBuilder sb = new SqlBuilder(StatementType.Select, typeof (Program));
       sb.AddConstraint(Operator.Equals, "idChannel", IdChannel);
+      sb.AddConstraint(Operator.Equals, "seriesId", seriesId);
       sb.AddConstraint(Operator.GreaterThan, "endTime", date);
       sb.AddConstraint(Operator.LessThanOrEquals, "startTime", date);
       sb.AddOrderByField(true, "startTime");
Index: TvEngine3/TVLibrary/TVDatabase/Program.cs
===================================================================
--- TvEngine3/TVLibrary/TVDatabase/Program.cs	(revision 27484)
+++ TvEngine3/TVLibrary/TVDatabase/Program.cs	(working copy)
@@ -50,6 +50,8 @@
     [TableColumn("starRating", NotNull = true)] private int starRating;
     [TableColumn("classification", NotNull = true)] private string classification;
     [TableColumn("parentalRating", NotNull = true)] private int parentalRating;
+    [TableColumn("seriesId", NotNull = false, NullValue = 0)] private int seriesId;
+    [TableColumn("seriesTermination", NotNull = false, NullValue = 0)] private int seriesTermination;
 
     #endregion
 
@@ -99,6 +101,7 @@
       this.parentalRating = parentalRating;
     }
 
+
     /// <summary> 
     /// Create an object from an existing row of data. This will be used by Gentle to 
     /// construct objects from retrieved rows. 
@@ -537,6 +540,38 @@
       }
     }
 
+    /// <summary>
+    /// Series Id is used only for Sky UK/IT/AU at the moment for 'series link' functionality
+    /// </summary>
+    public int SeriesId
+    {
+      get
+      {
+        return seriesId;
+      }
+      set
+      {
+        isChanged |= seriesId != value;
+        seriesId = value;
+      }
+    }
+
+    /// <summary>
+    /// Does this program terminate a series?  The schedule can be deleted when it is time to record this program is so
+    /// </summary>
+    public int SeriesTermination
+    {
+      get
+      {
+        return seriesTermination;
+      }
+      set
+      {
+        isChanged |= seriesTermination != value;
+        seriesTermination = value;
+      }
+    }
+
     #endregion
 
     #region Storage and Retrieval
@@ -893,6 +928,26 @@
       return ObjectFactory.GetCollection<Program>(stmt.Execute());
     }
 
+    /// <summary>
+    /// Gets all programs with the specified series id (series link - Sky UK/IT/AU)
+    /// </summary>
+    /// <param name="seriesId"></param>
+    /// <param name="channelId"></param>
+    /// <returns></returns>
+    public static IList<Program> RetrieveBySeriesId(int seriesId, int channelId)
+    {
+      SqlBuilder sb = new SqlBuilder(StatementType.Select, typeof(Program));
+
+      //  Add constraints (series id and channel id)
+      sb.AddConstraint(Operator.Equals, "idChannel", channelId);
+      sb.AddConstraint(Operator.Equals, "seriesId", seriesId);
+
+      SqlStatement stmt = sb.GetStatement(true);
+
+      // execute the statement/query and create a collection of User instances from the result set
+      return ObjectFactory.GetCollection<Program>(stmt.Execute());
+    }
+
     public static void ResetPendingState(int idProgram)
     {
       Program prg = Program.Retrieve(idProgram);
@@ -1169,6 +1224,10 @@
                               OriginalAirDate,
                               SeriesNum, EpisodeNum, EpisodeName, EpisodePart, StarRating, Classification,
                               parentalRating);
+
+      p.SeriesId = SeriesId;
+      p.SeriesTermination = SeriesTermination;
+
       return p;
     }
 
Index: TvEngine3/TVLibrary/TVDatabase/Schedule.cs
===================================================================
--- TvEngine3/TVLibrary/TVDatabase/Schedule.cs	(revision 27484)
+++ TvEngine3/TVLibrary/TVDatabase/Schedule.cs	(working copy)
@@ -43,7 +43,8 @@
     EveryTimeOnEveryChannel,
     Weekends,
     WorkingDays,
-    WeeklyEveryTimeOnThisChannel
+    WeeklyEveryTimeOnThisChannel,
+    SeriesLink,
   }
 
   /// <summary>
@@ -98,6 +99,8 @@
     private int recommendedCard;
     [TableColumn("series", NotNull = true)]
     private bool series;
+    [TableColumn("seriesId", NotNull = false, NullValue = 0)]
+    private int seriesId;
 
     #endregion
 
@@ -451,6 +454,21 @@
       }
     }
 
+    /// <summary>
+    /// Gets/Sets the series id
+    /// </summary>
+    public int SeriesId
+    {
+      get
+      {
+        return seriesId;
+      }
+      set
+      {
+        seriesId = value;
+      }
+    }
+
     #endregion
 
     #region Storage and Retrieval
@@ -759,6 +777,24 @@
               }
             }
             break;
+
+          case (int)ScheduleRecordingType.SeriesLink:
+            List<Program> programsSeriesLink =
+              (List<Program>)
+              Program.RetrieveBySeriesId(schedule.SeriesId, schedule.ReferencedChannel().IdChannel);
+
+            if (programsSeriesLink != null && programsSeriesLink.Count > 0)
+            {
+              foreach (Program programSeriesLink in programsSeriesLink)
+              {
+                if (!schedule.IsSerieIsCanceled(programSeriesLink.StartTime))
+                {
+                  SetAdvScheduleState(schedule, clear, programSeriesLink);
+                }
+              }
+            }
+
+            break;
         }
       }
       catch (Exception e)
@@ -788,7 +824,8 @@
     {
       if (schedule.ScheduleType == (int)ScheduleRecordingType.EveryTimeOnEveryChannel ||
           schedule.ScheduleType == (int)ScheduleRecordingType.EveryTimeOnThisChannel ||
-		  schedule.ScheduleType == (int)ScheduleRecordingType.WeeklyEveryTimeOnThisChannel)
+		  schedule.ScheduleType == (int)ScheduleRecordingType.WeeklyEveryTimeOnThisChannel ||
+          schedule.ScheduleType == (int)ScheduleRecordingType.SeriesLink)
       {
         return false;
       }
@@ -1170,6 +1207,16 @@
             return true;
           }
           break;
+        case ScheduleRecordingType.SeriesLink:
+          if (program.SeriesId == SeriesId && program.IdChannel == IdChannel)
+          {
+            if (filterCanceledRecordings && IsSerieIsCanceled(program.StartTime, program.IdChannel))
+            {
+              return false;
+            }
+            return true;
+          }
+          break;
         case ScheduleRecordingType.Daily:
           if (program.IdChannel == IdChannel)
           {
@@ -1410,6 +1457,9 @@
       schedule.series = series;
       schedule.idSchedule = idSchedule;
       schedule.isChanged = false;
+
+      schedule.seriesId = seriesId;
+
       return schedule;
     }
 
Index: TvEngine3/TVLibrary/TVDatabase/TuningDetail.cs
===================================================================
--- TvEngine3/TVLibrary/TVDatabase/TuningDetail.cs	(revision 27484)
+++ TvEngine3/TVLibrary/TVDatabase/TuningDetail.cs	(working copy)
@@ -654,6 +654,32 @@
     }
 
     /// <summary>
+    /// Finds all matching tuning detail entries
+    /// </summary>
+    /// <param name="frequency"></param>
+    /// <param name="frequenyTolerance"></param>
+    /// <param name="polarisation"></param>
+    /// <param name="innerFEC"></param>
+    /// <param name="symbolRate"></param>
+    /// <param name="networkId"></param>
+    /// <returns></returns>
+    public static IList<TuningDetail> Find(int frequency, int frequenyTolerance, int polarisation, int innerFEC, int symbolRate, int networkId)
+    {
+      SqlBuilder sb = new SqlBuilder(StatementType.Select, typeof(TuningDetail));
+
+      sb.AddConstraint(Operator.GreaterThanOrEquals, "frequency", (frequency - frequenyTolerance));
+      sb.AddConstraint(Operator.LessThanOrEquals, "frequency", (frequency + frequenyTolerance));
+      sb.AddConstraint(Operator.Equals, "polarisation", polarisation);
+      sb.AddConstraint(Operator.Equals, "innerFecRate", innerFEC);
+      sb.AddConstraint(Operator.Equals, "symbolrate", symbolRate);
+      sb.AddConstraint(Operator.Equals, "networkId", networkId);
+
+      SqlStatement stmt = sb.GetStatement(true);
+
+      return ObjectFactory.GetCollection<TuningDetail>(stmt.Execute());
+    }
+
+    /// <summary>
     /// Persists the entity if it was never persisted or was changed.
     /// </summary>
     public override void Persist()
Index: TvEngine3/TVLibrary/TVDatabase/TvBusinessLayer/BusinessLayer.cs
===================================================================
--- TvEngine3/TVLibrary/TVDatabase/TvBusinessLayer/BusinessLayer.cs	(revision 27484)
+++ TvEngine3/TVLibrary/TVDatabase/TvBusinessLayer/BusinessLayer.cs	(working copy)
@@ -1434,6 +1434,9 @@
           Convert.ToInt32(prog["parentalRating"])
           );
 
+        p.SeriesId = Convert.ToInt32((prog.IsNull("seriesId") ? 0 : prog["seriesId"]));
+        p.SeriesTermination = Convert.ToInt32((prog.IsNull("seriesTermination") ? 0 : prog["seriesTermination"]));
+
         int idChannel = p.IdChannel;
         if (!maps.ContainsKey(idChannel))
         {
Index: TvEngine3/TVLibrary/TVDatabase/TvBusinessLayer/EpgDBUpdater.cs
===================================================================
--- TvEngine3/TVLibrary/TVDatabase/TvBusinessLayer/EpgDBUpdater.cs	(revision 27484)
+++ TvEngine3/TVLibrary/TVDatabase/TvBusinessLayer/EpgDBUpdater.cs	(working copy)
@@ -459,6 +459,15 @@
         dbProg.OriginalAirDate = SqlDateTime.MinValue.Value; // TODO: /!\ add implementation
         dbProg.ClearRecordPendingState();
       }
+
+      //  If the epg program has series id information, copy to the program
+      if (ep.SeriesId != 0)
+      {
+        dbProg.SeriesId = ep.SeriesId;
+        dbProg.SeriesTermination = ep.SeriesTermination;
+      }
+
+
       dbProg.Persist();
     }
 
Index: TvEngine3/TVLibrary/TvLibrary.Interfaces/Epg/EpgProgram.cs
===================================================================
--- TvEngine3/TVLibrary/TvLibrary.Interfaces/Epg/EpgProgram.cs	(revision 27484)
+++ TvEngine3/TVLibrary/TvLibrary.Interfaces/Epg/EpgProgram.cs	(working copy)
@@ -34,6 +34,8 @@
     private List<EpgLanguageText> _languageText;
     private DateTime _startTime;
     private DateTime _endTime;
+    private int _seriesId;
+    private int _seriesTermination;
 
     #endregion
 
@@ -85,6 +87,24 @@
       set { _endTime = value; }
     }
 
+    /// <summary>
+    /// Gets/Sets the series id (used for 'series link' for Sky UK/IT/AU)
+    /// </summary>
+    public int SeriesId
+    {
+      get { return _seriesId; }
+      set { _seriesId = value; }
+    }
+
+    /// <summary>
+    /// Gets/Sets the series termination flag (used to designate last episode of a series for Sky UK/IT/AU)
+    /// </summary>
+    public int SeriesTermination
+    {
+      get { return _seriesTermination; }
+      set { _seriesTermination = value; }
+    }
+
     #endregion
 
     #region IComparable<EpgProgram> Members
Index: TvEngine3/TVLibrary/TvLibrary.Interfaces/Interfaces/ITVEPG.cs
===================================================================
--- TvEngine3/TVLibrary/TvLibrary.Interfaces/Interfaces/ITVEPG.cs	(revision 27484)
+++ TvEngine3/TVLibrary/TvLibrary.Interfaces/Interfaces/ITVEPG.cs	(working copy)
@@ -46,6 +46,27 @@
   public abstract class BaseEpgGrabber : IEpgCallback
   {
     /// <summary>
+    /// EPG grab mode
+    /// </summary>
+    public enum eEPGGrabMode
+    {
+      Normal,
+      SkyUK,
+      SkyItaly,
+    }
+
+    /// <summary>
+    /// Gets the current EPG grab mode
+    /// </summary>
+    public virtual eEPGGrabMode EPGGrabMode
+    {
+      get
+      {
+        return eEPGGrabMode.Normal;
+      }
+    }
+
+    /// <summary>
     /// Gets called when epg has been cancelled
     /// Should be overriden by the class
     /// </summary>
Index: TvEngine3/TVLibrary/TVLibrary/Implementations/DVB/Graphs/TvCardDvbBase.cs
===================================================================
--- TvEngine3/TVLibrary/TVLibrary/Implementations/DVB/Graphs/TvCardDvbBase.cs	(revision 27484)
+++ TvEngine3/TVLibrary/TVLibrary/Implementations/DVB/Graphs/TvCardDvbBase.cs	(working copy)
@@ -29,11 +29,13 @@
 using TvLibrary.Interfaces.Analyzer;
 using TvLibrary.Channels;
 using TvLibrary.Implementations.Helper;
+using TvLibrary.Implementations.Helper.Providers;
 using TvLibrary.Epg;
 using TvLibrary.ChannelLinkage;
 using MediaPortal.TV.Epg;
 using TvDatabase;
 
+
 namespace TvLibrary.Implementations.DVB
 {
 
@@ -795,6 +797,9 @@
     {
       //UpdateSignalQuality(true);
       bool isLocked = false;
+      bool isPresent = false;
+      int quality = 0;
+      int strength = 0;
       DateTime timeStart = DateTime.Now;
       TimeSpan ts = timeStart - timeStart;
       while (!isLocked && ts.TotalSeconds < _parameters.TimeOutTune)
@@ -806,9 +811,14 @@
           try
           {
             stat.get_SignalLocked(out isLocked);
-            if (isLocked)
+            stat.get_SignalPresent(out isPresent);
+            stat.get_SignalQuality(out quality);
+            stat.get_SignalStrength(out strength);
+            Log.Log.WriteFile("dvb:  LockedInOnSignal locked: {0}, present: {1}, quality: {2}, strength: {3}", isLocked, isPresent, quality, strength);
+            if (isLocked || (isPresent && (quality > 0 || strength > 0)))
             {
-              break;
+                isLocked = true;
+                break;
             }
           }
           catch (COMException)
@@ -2341,6 +2351,14 @@
       _interfaceEpgGrabber.SetCallBack(callback);
       _interfaceEpgGrabber.GrabEPG();
       _interfaceEpgGrabber.GrabMHW();
+
+      // If grabbing for a provider (Sky UK/Italy)
+      if (callback.EPGGrabMode == BaseEpgGrabber.eEPGGrabMode.SkyUK)
+        _interfaceEpgGrabber.ActivateSkyEpgGrabber(SkyUK.Instance.InternalId);
+
+      else if (callback.EPGGrabMode == BaseEpgGrabber.eEPGGrabMode.SkyItaly)
+        _interfaceEpgGrabber.ActivateSkyEpgGrabber(SkyItaly.Instance.InternalId);
+
       _epgGrabbing = true;
     }
 
@@ -2389,6 +2407,143 @@
         //if (!CheckThreadId()) return null;
         try
         {
+          byte isSkyEpgGrabbingActive = 0;
+          byte isSkyEpgReady = 0;
+          byte hasSkyEpgGrabbingAborted = 0;
+          _interfaceEpgGrabber.IsSkyEpgGrabberActive(ref isSkyEpgGrabbingActive);
+          _interfaceEpgGrabber.IsSkyEpgReady(ref isSkyEpgReady);
+          _interfaceEpgGrabber.HasSkyEpgAborted(ref hasSkyEpgGrabbingAborted);
+
+          List<EpgChannel> epgChannels = new List<EpgChannel>();
+
+          if (isSkyEpgGrabbingActive == 1 && hasSkyEpgGrabbingAborted == 1)
+          {
+            Log.Log.Write("Sky EPG grabbing detected as being aborted");
+
+            _interfaceEpgGrabber.ResetSkyEpgRetrieval();
+            _interfaceEpgGrabber.Reset();
+            return epgChannels;
+          }
+
+          if (isSkyEpgGrabbingActive == 1 && isSkyEpgReady == 1)
+          {
+            //  Reset the epg retrieval
+            _interfaceEpgGrabber.ResetSkyEpgRetrieval();
+
+            byte atEndChannel = 0;
+            ushort channelId = 0;
+            ushort networkId = 0;
+            ushort transportId = 0;
+            ushort serviceId = 0;
+            int numberSkyEpgEventsRetrieved = 0;
+
+            //  Get the first channel
+            _interfaceEpgGrabber.GetNextSkyEpgChannel(ref atEndChannel, ref channelId, ref networkId, ref transportId, ref serviceId);
+
+            //  While we have more channels to retrieve
+            while (atEndChannel == 0)
+            {
+              byte atEndChannelEvent = 0;
+              ushort eventId = 0;
+              ushort mjdStart = 0;
+              uint startTime = 0;
+              uint duration = 0;
+              IntPtr titlePtr;
+              IntPtr summaryPtr;
+              IntPtr themePtr;
+              ushort seriesId = 0;
+              byte seriesTermination = 0;
+
+              //  Get the first event for this channel
+              _interfaceEpgGrabber.GetNextSkyEpgChannelEvent(ref atEndChannelEvent, ref eventId, ref mjdStart, ref startTime, ref duration, out titlePtr, out summaryPtr, out themePtr, ref seriesId, ref seriesTermination);
+
+              //  Try to find this channel
+              EpgChannel skyEpgChannel = null;
+              
+              if(atEndChannelEvent == 0)
+              {
+                skyEpgChannel = new EpgChannel();
+
+                //  Add and populate the epg channel
+                epgChannels.Add(skyEpgChannel);
+
+                DVBBaseChannel baseChannel = new DVBSChannel();
+                baseChannel.NetworkId = networkId;
+                baseChannel.TransportId = transportId;
+                baseChannel.ServiceId = serviceId;
+                baseChannel.Name = string.Empty;
+
+                skyEpgChannel.Channel = baseChannel;
+              }
+
+              while (atEndChannelEvent == 0)
+              {
+                //  Validate the timestamps
+                if (mjdStart != 0 && duration != 0)
+                {
+                  //  Convert modified Julian day and calculate start and end time
+                  DateTime programStartDay = (new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).AddSeconds((mjdStart + 2400000.5 - 2440587.5) * 86400);
+                  DateTime programStartTime = programStartDay.AddSeconds(startTime);
+
+                  //  Start time is in UTC, need to convert to local time
+                  programStartTime = programStartTime.ToLocalTime();
+                    
+                  //  Calculate end time
+                  DateTime programEndTime = programStartTime.AddSeconds(duration);
+
+                  string title = string.Empty;
+                  string summary = string.Empty;
+                  string theme = string.Empty;
+
+                  if (titlePtr != IntPtr.Zero)
+                    title = DvbTextConverter.Convert(titlePtr, "");
+
+                  if (summaryPtr != IntPtr.Zero)
+                    summary = DvbTextConverter.Convert(summaryPtr, "");
+
+                  if (themePtr != IntPtr.Zero)
+                    theme = DvbTextConverter.Convert(themePtr, "");
+
+                  //  Populate and add the program
+                  EpgProgram skyProgram = new EpgProgram(programStartTime, programEndTime);
+                  EpgLanguageText skyProgramLang = new EpgLanguageText("ALL", title, summary, theme, 0, "", -1);
+                  skyProgram.Text.Add(skyProgramLang);
+
+                  //  Add the series id, if applicable
+                  if (seriesId != 0)
+                  {
+                    skyProgram.SeriesId = seriesId;
+                    skyProgram.SeriesTermination = seriesTermination;
+                  }
+
+                  skyEpgChannel.Programs.Add(skyProgram);
+
+                  numberSkyEpgEventsRetrieved++;
+                }
+
+                //  Get the next channel event
+                _interfaceEpgGrabber.GetNextSkyEpgChannelEvent(ref atEndChannelEvent, ref eventId, ref mjdStart, ref startTime, ref duration, out titlePtr, out summaryPtr, out themePtr, ref seriesId, ref seriesTermination);
+              }
+
+              //  Sort the programs
+              if (skyEpgChannel != null)
+                skyEpgChannel.Sort();
+
+              //  Get the next channel
+              _interfaceEpgGrabber.GetNextSkyEpgChannel(ref atEndChannel, ref channelId, ref networkId, ref transportId, ref serviceId);
+            }
+
+            Log.Log.Epg("Retrieved EPG events for " + epgChannels.Count.ToString() + " channels");
+            Log.Log.Epg("Number of Sky epg events retrieved: " + numberSkyEpgEventsRetrieved.ToString());
+
+            //  Reset to clear utilised memory
+            _interfaceEpgGrabber.Reset();
+
+            //  All done!  Return the epg channels and the program data!
+            return epgChannels;
+          }
+
+
           bool dvbReady, mhwReady;
           _interfaceEpgGrabber.IsEPGReady(out dvbReady);
           _interfaceEpgGrabber.IsMHWReady(out mhwReady);
@@ -2400,7 +2555,6 @@
           mhwReady = titleCount > 10;
           _interfaceEpgGrabber.GetEPGChannelCount(out channelCount);
           dvbReady = channelCount > 0;
-          List<EpgChannel> epgChannels = new List<EpgChannel>();
           Log.Log.Epg("dvb:mhw ready MHW {0} titles found", titleCount);
           Log.Log.Epg("dvb:dvb ready.EPG {0} channels", channelCount);
           if (mhwReady)
@@ -2483,6 +2637,7 @@
             return epgChannels;
           }
 
+
           if (dvbReady)
           {
             ushort networkid = 0;
Index: TvEngine3/TVLibrary/TVLibrary/Implementations/Helper/Providers/Provider.cs
===================================================================
--- TvEngine3/TVLibrary/TVLibrary/Implementations/Helper/Providers/Provider.cs	(revision 0)
+++ TvEngine3/TVLibrary/TVLibrary/Implementations/Helper/Providers/Provider.cs	(revision 0)
@@ -0,0 +1,128 @@
+// Copyright (C) 2005-2010 Team MediaPortal
+// http://www.team-mediaportal.com
+// 
+// MediaPortal is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+// 
+// MediaPortal is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with MediaPortal. If not, see <http://www.gnu.org/licenses/>.
+
+
+using System;
+using System.Collections.Generic;
+using TvLibrary.Interfaces;
+using TvLibrary.Interfaces.Analyzer;
+using TvLibrary.Channels;
+using TvDatabase;
+
+namespace TvLibrary.Implementations.Helper.Providers
+{
+  public class Provider
+  {
+    #region Fields
+
+    /// <summary>
+    /// Singleton
+    /// </summary>
+    private static readonly Provider _instance = new Provider();
+
+    #endregion
+
+    #region Properties
+
+    /// <summary>
+    /// Gets the singleton instance
+    /// </summary>
+    public static Provider Instance
+    {
+      get
+      {
+        return _instance;
+      }
+    }
+
+    /// <summary>
+    /// Gets if at least 1 provider has EPG grabbing enabled
+    /// </summary>
+    public bool ProviderEPGGrabbingEnabled
+    {
+      get
+      {
+        return SkyUK.Instance.EPGGrabbingEnabled || SkyItaly.Instance.EPGGrabbingEnabled;
+      }
+    }
+
+    #endregion
+
+    #region Methods
+
+    /// <summary>
+    /// Protected cstr
+    /// </summary>
+    protected Provider()
+    { }
+
+    /// <summary>
+    /// Sets a setting value
+    /// </summary>
+    /// <param name="name"></param>
+    /// <param name="value"></param>
+    protected void SetSetting(string name, object value)
+    {
+      TvBusinessLayer layer = new TvBusinessLayer();
+
+      string valueString;
+
+      if (value is bool)
+        valueString = (((bool)value) ? "true" : "false");
+      else
+        valueString = value.ToString();
+
+      Setting setting = layer.GetSetting(name);
+      setting.Value = valueString;
+      setting.Persist();
+    }
+
+    /// <summary>
+    /// Gets a setting value
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+    /// <param name="name"></param>
+    /// <returns></returns>
+    protected T GetSetting<T>(string name, T defaultValue)
+    {
+      TvBusinessLayer layer = new TvBusinessLayer();
+
+      if (typeof(T) == typeof(int))
+      {
+        int parsedIntValue = (int)(object)defaultValue;
+
+        int.TryParse(layer.GetSetting(name, parsedIntValue.ToString()).Value, out parsedIntValue);
+        return (T)(object)parsedIntValue;
+      }
+
+      if (typeof(T) == typeof(bool))
+      {
+        bool parsedBoolValue = (layer.GetSetting(name, ((bool)(object)defaultValue ? "true" : "false")).Value == "true" ? true : false);
+
+        return (T)(object)parsedBoolValue;
+      }
+
+      if (typeof(T) == typeof(string))
+      {
+        return (T)(object)layer.GetSetting(name, (string)(object)defaultValue).Value;
+      }
+
+      throw new Exception("Invalid type");
+    }
+
+    #endregion
+  }
+}
Index: TvEngine3/TVLibrary/TVLibrary/Implementations/Helper/Providers/SkyItaly.cs
===================================================================
--- TvEngine3/TVLibrary/TVLibrary/Implementations/Helper/Providers/SkyItaly.cs	(revision 0)
+++ TvEngine3/TVLibrary/TVLibrary/Implementations/Helper/Providers/SkyItaly.cs	(revision 0)
@@ -0,0 +1,339 @@
+// Copyright (C) 2005-2010 Team MediaPortal
+// http://www.team-mediaportal.com
+// 
+// MediaPortal is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+// 
+// MediaPortal is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with MediaPortal. If not, see <http://www.gnu.org/licenses/>.
+
+
+using System;
+using System.Collections.Generic;
+using TvLibrary.Interfaces;
+using TvLibrary.Interfaces.Analyzer;
+using TvLibrary.Channels;
+using TvDatabase;
+using DirectShowLib.BDA;
+
+namespace TvLibrary.Implementations.Helper.Providers
+{
+
+  /// <summary>
+  /// Helper class for provider specific functionality
+  /// </summary>
+  public class SkyItaly
+    : Provider
+  {
+    #region Fields
+
+    /// <summary>
+    /// Singleton instance
+    /// </summary>
+    private static readonly SkyItaly _instance = new SkyItaly();
+
+    private const uint INTERNAL_ID = 0x02;
+
+    private const int SKY_ITALY_DEFAULT_TRANSPONDER_FREQUENCY = 11881000;
+    private const string SKY_ITALY_DEFAULT_TRANSPONDER_POLARISATION = "Vertical";
+    private const int SKY_ITALY_DEFAULT_TRANSPONDER_SYMBOL_RATE = 27500;
+    private const string SKY_ITALY_DEFAULT_TRANSPONDER_INNER_FEC = "3/4";
+    private const int SKY_ITALY_DEFAULT_NETWORK_ID = 0xFBFF;
+
+    #endregion
+
+    #region Properties
+
+    /// <summary>
+    /// Gets the internal id for Sky Italy
+    /// </summary>
+    public uint InternalId
+    {
+      get
+      {
+        return INTERNAL_ID;
+      }
+    }
+
+    /// <summary>
+    /// Gets the instance
+    /// </summary>
+    public static SkyItaly Instance
+    {
+      get
+      {
+        return _instance;
+      }
+    }
+
+    /// <summary>
+    /// Gets if the EPG should be grabbed for Sky Italy
+    /// </summary>
+    public bool EPGGrabbingEnabled
+    {
+      get
+      {
+        return GetSetting<bool>("SkyItalyGrabEPG", false);
+      }
+      set
+      {
+        SetSetting("SkyItalyGrabEPG", value);
+      }
+    }
+
+    /// <summary>
+    /// Gets/Sets the last epg grab time
+    /// </summary>
+    public DateTime LastEPGGrabTime
+    {
+      get
+      {
+        DateTime lastGrabTime = DateTime.MinValue;
+
+        DateTime.TryParse(GetSetting<string>("SkyItalyLastEPGGrabTime", DateTime.MinValue.ToString()), out lastGrabTime);
+
+        return lastGrabTime;
+      }
+      set
+      {
+        SetSetting("SkyItalyLastEPGGrabTime", value.ToString());
+      }
+    }
+
+    /// <summary>
+    /// Gets/Sets the default transponder frequency
+    /// </summary>
+    public int DefaultTransponderFrequency
+    {
+      get
+      {
+        return GetSetting<int>("SkyItalyDefaultTransponderFrequency", SKY_ITALY_DEFAULT_TRANSPONDER_FREQUENCY);
+      }
+      set
+      {
+        SetSetting("SkyItalyDefaultTransponderFrequency", value);
+      }
+    }
+
+    /// <summary>
+    /// Gets/Sets the default transponder polarisation
+    /// </summary>
+    public string DefaultTransponderPolarisationString
+    {
+      get
+      {
+        return GetSetting<string>("SkyItalyDefaultTransponderPolarisation", SKY_ITALY_DEFAULT_TRANSPONDER_POLARISATION);
+      }
+      set
+      {
+        SetSetting("SkyItalyDefaultTransponderPolarisation", value);
+      }
+    }
+
+    public Polarisation DefaultTransponderPolarisation
+    {
+      get
+      {
+        switch (DefaultTransponderPolarisationString)
+        {
+          case "Horizontal":
+            return Polarisation.LinearH;
+          case "Vertical":
+            return Polarisation.LinearV;
+          case "Circular Left":
+            return Polarisation.CircularL;
+          case "Circular Right":
+            return Polarisation.CircularR;
+        }
+
+        return Polarisation.LinearV;
+      }
+      set
+      {
+        switch (value)
+        {
+          case Polarisation.LinearH:
+            DefaultTransponderPolarisationString = "Horizontal";
+            break;
+          case Polarisation.LinearV:
+            DefaultTransponderPolarisationString = "Vertical";
+            break;
+          case Polarisation.CircularL:
+            DefaultTransponderPolarisationString = "Circular Left";
+            break;
+          case Polarisation.CircularR:
+            DefaultTransponderPolarisationString = "Circular Right";
+            break;
+
+          default:
+            DefaultTransponderPolarisationString = SKY_ITALY_DEFAULT_TRANSPONDER_POLARISATION;
+            break;
+        }
+      }
+    }
+
+    /// <summary>
+    /// Gets/Sets the default transponder symbol rate
+    /// </summary>
+    public int DefaultTransponderSymbolRate
+    {
+      get
+      {
+        return GetSetting<int>("SkyItalyDefaultTransponderSymbolRate", SKY_ITALY_DEFAULT_TRANSPONDER_SYMBOL_RATE);
+      }
+      set
+      {
+        SetSetting("SkyItalyDefaultTransponderSymbolRate", value);
+      }
+    }
+
+    /// <summary>
+    /// Gets/Sets the default transponder inner FEC
+    /// </summary>
+    public string DefaultTransponderInnerFECString
+    {
+      get
+      {
+        return GetSetting<string>("SkyItalyDefaultTransponderInnerFEC", SKY_ITALY_DEFAULT_TRANSPONDER_INNER_FEC);
+      }
+      set
+      {
+        SetSetting("SkyItalyDefaultTransponderInnerFEC", value);
+      }
+    }
+
+    /// <summary>
+    /// Gets the default transponder inner FEC
+    /// </summary>
+    public BinaryConvolutionCodeRate DefaultTransponderInnerFEC
+    {
+      get
+      {
+        switch (DefaultTransponderInnerFECString)
+        {
+          case "1/2":
+            return BinaryConvolutionCodeRate.Rate1_2;
+          case "1/3":
+            return BinaryConvolutionCodeRate.Rate1_3;
+          case "1/4":
+            return BinaryConvolutionCodeRate.Rate1_4;
+          case "2/3":
+            return BinaryConvolutionCodeRate.Rate2_3;
+          case "2/5":
+            return BinaryConvolutionCodeRate.Rate2_5;
+          case "3/4":
+            return BinaryConvolutionCodeRate.Rate3_4;
+          case "3/5":
+            return BinaryConvolutionCodeRate.Rate3_5;
+          case "4/5":
+            return BinaryConvolutionCodeRate.Rate4_5;
+          case "5/11":
+            return BinaryConvolutionCodeRate.Rate5_11;
+          case "5/6":
+            return BinaryConvolutionCodeRate.Rate5_6;
+          case "7/8":
+            return BinaryConvolutionCodeRate.Rate7_8;
+          case "8/9":
+            return BinaryConvolutionCodeRate.Rate8_9;
+          case "9/10":
+            return BinaryConvolutionCodeRate.Rate9_10;
+        }
+
+        return BinaryConvolutionCodeRate.Rate2_3;
+      }
+      set
+      {
+        switch (value)
+        {
+          case BinaryConvolutionCodeRate.Rate1_2:
+            DefaultTransponderInnerFECString = "1/2";
+            break;
+          case BinaryConvolutionCodeRate.Rate1_3:
+            DefaultTransponderInnerFECString = "1/3";
+            break;
+          case BinaryConvolutionCodeRate.Rate1_4:
+            DefaultTransponderInnerFECString = "1/4";
+            break;
+          case BinaryConvolutionCodeRate.Rate2_3:
+            DefaultTransponderInnerFECString = "2/3";
+            break;
+          case BinaryConvolutionCodeRate.Rate2_5:
+            DefaultTransponderInnerFECString = "2/5";
+            break;
+          case BinaryConvolutionCodeRate.Rate3_4:
+            DefaultTransponderInnerFECString = "3/4";
+            break;
+          case BinaryConvolutionCodeRate.Rate3_5:
+            DefaultTransponderInnerFECString = "3/5";
+            break;
+          case BinaryConvolutionCodeRate.Rate4_5:
+            DefaultTransponderInnerFECString = "4/5";
+            break;
+          case BinaryConvolutionCodeRate.Rate5_11:
+            DefaultTransponderInnerFECString = "5/11";
+            break;
+          case BinaryConvolutionCodeRate.Rate5_6:
+            DefaultTransponderInnerFECString = "5/6";
+            break;
+          case BinaryConvolutionCodeRate.Rate6_7:
+            DefaultTransponderInnerFECString = "6/7";
+            break;
+          case BinaryConvolutionCodeRate.Rate7_8:
+            DefaultTransponderInnerFECString = "7/8";
+            break;
+          case BinaryConvolutionCodeRate.Rate8_9:
+            DefaultTransponderInnerFECString = "8/9";
+            break;
+          case BinaryConvolutionCodeRate.Rate9_10:
+            DefaultTransponderInnerFECString = "9/10";
+            break;
+
+          default:
+            DefaultTransponderInnerFECString = "2/3";
+            break;
+        }
+      }
+    }
+
+    /// <summary>
+    /// Gets/Sets the default transponder symbol rate
+    /// </summary>
+    public int NetworkId
+    {
+      get
+      {
+        return GetSetting<int>("SkyItalyNetworkId", SKY_ITALY_DEFAULT_NETWORK_ID);
+      }
+      set
+      {
+        SetSetting("SkyItalyNetworkId", value);
+      }
+    }
+
+    #endregion
+
+    #region Methods
+
+    /// <summary>
+    /// Resets the default transponder parameters
+    /// </summary>
+    public void ResetDefaultTransponderParameters()
+    {
+      DefaultTransponderFrequency = SKY_ITALY_DEFAULT_TRANSPONDER_FREQUENCY;
+      DefaultTransponderPolarisationString = SKY_ITALY_DEFAULT_TRANSPONDER_POLARISATION;
+      DefaultTransponderSymbolRate = SKY_ITALY_DEFAULT_TRANSPONDER_SYMBOL_RATE;
+      DefaultTransponderInnerFECString = SKY_ITALY_DEFAULT_TRANSPONDER_INNER_FEC;
+      NetworkId = SKY_ITALY_DEFAULT_NETWORK_ID;
+    }
+
+    #endregion
+
+  }
+}
Index: TvEngine3/TVLibrary/TVLibrary/Implementations/Helper/Providers/SkyUK.cs
===================================================================
--- TvEngine3/TVLibrary/TVLibrary/Implementations/Helper/Providers/SkyUK.cs	(revision 0)
+++ TvEngine3/TVLibrary/TVLibrary/Implementations/Helper/Providers/SkyUK.cs	(revision 0)
@@ -0,0 +1,339 @@
+// Copyright (C) 2005-2010 Team MediaPortal
+// http://www.team-mediaportal.com
+// 
+// MediaPortal is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+// 
+// MediaPortal is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with MediaPortal. If not, see <http://www.gnu.org/licenses/>.
+
+
+using System;
+using System.Collections.Generic;
+using TvLibrary.Interfaces;
+using TvLibrary.Interfaces.Analyzer;
+using TvLibrary.Channels;
+using TvDatabase;
+using DirectShowLib.BDA;
+
+namespace TvLibrary.Implementations.Helper.Providers
+{
+
+  /// <summary>
+  /// Helper class for provider specific functionality
+  /// </summary>
+  public class SkyUK
+    : Provider
+  {
+    #region Fields
+
+    /// <summary>
+    /// Singleton instance
+    /// </summary>
+    private static readonly SkyUK _instance = new SkyUK();
+
+    private const uint INTERNAL_ID = 0x01;
+
+    private const int SKY_UK_DEFAULT_TRANSPONDER_FREQUENCY = 11778000;
+    private const string SKY_UK_DEFAULT_TRANSPONDER_POLARISATION = "Vertical";
+    private const int SKY_UK_DEFAULT_TRANSPONDER_SYMBOL_RATE = 27500;
+    private const string SKY_UK_DEFAULT_TRANSPONDER_INNER_FEC = "2/3";
+    private const int SKY_UK_DEFAULT_NETWORK_ID = 0x2;
+
+    #endregion
+
+    #region Properties
+
+    /// <summary>
+    /// Gets the internal id for Sky UK
+    /// </summary>
+    public uint InternalId
+    {
+      get
+      {
+        return INTERNAL_ID;
+      }
+    }
+
+    /// <summary>
+    /// Gets the instance
+    /// </summary>
+    public static SkyUK Instance
+    {
+      get
+      {
+        return _instance;
+      }
+    }
+
+    /// <summary>
+    /// Gets/Sets if the EPG should be grabbed for Sky UK
+    /// </summary>
+    public bool EPGGrabbingEnabled
+    {
+      get
+      {
+        return GetSetting<bool>("SkyUKGrabEPG", false);
+      }
+      set
+      {
+        SetSetting("SkyUKGrabEPG", value);
+      }
+    }
+
+    /// <summary>
+    /// Gets/Sets the last epg grab time
+    /// </summary>
+    public DateTime LastEPGGrabTime
+    {
+      get
+      {
+        DateTime lastGrabTime = DateTime.MinValue;
+
+        DateTime.TryParse(GetSetting<string>("SkyUKLastEPGGrabTime", DateTime.MinValue.ToString()), out lastGrabTime);
+
+        return lastGrabTime;
+      }
+      set
+      {
+        SetSetting("SkyUKLastEPGGrabTime", value.ToString());
+      }
+    }
+
+    /// <summary>
+    /// Gets/Sets the default transponder frequency
+    /// </summary>
+    public int DefaultTransponderFrequency
+    {
+      get
+      {
+        return GetSetting<int>("SkyUKDefaultTransponderFrequency", SKY_UK_DEFAULT_TRANSPONDER_FREQUENCY);
+      }
+      set
+      {
+        SetSetting("SkyUKDefaultTransponderFrequency", value);
+      }
+    }
+
+    /// <summary>
+    /// Gets/Sets the default transponder polarisation
+    /// </summary>
+    public string DefaultTransponderPolarisationString
+    {
+      get
+      {
+        return GetSetting<string>("SkyUKDefaultTransponderPolarisation", SKY_UK_DEFAULT_TRANSPONDER_POLARISATION);
+      }
+      set
+      {
+        SetSetting("SkyUKDefaultTransponderPolarisation", value);
+      }
+    }
+
+    public Polarisation DefaultTransponderPolarisation
+    {
+      get
+      {
+        switch (DefaultTransponderPolarisationString)
+        {
+          case "Horizontal":
+            return Polarisation.LinearH;
+          case "Vertical":
+            return Polarisation.LinearV;
+          case "Circular Left":
+            return Polarisation.CircularL;
+          case "Circular Right":
+            return Polarisation.CircularR;
+        }
+
+        return Polarisation.LinearV;
+      }
+      set
+      {
+        switch (value)
+        {
+          case Polarisation.LinearH:
+            DefaultTransponderPolarisationString = "Horizontal";
+            break;
+          case Polarisation.LinearV:
+            DefaultTransponderPolarisationString = "Vertical";
+            break;
+          case Polarisation.CircularL:
+            DefaultTransponderPolarisationString = "Circular Left";
+            break;
+          case Polarisation.CircularR:
+            DefaultTransponderPolarisationString = "Circular Right";
+            break;
+
+          default:
+            DefaultTransponderPolarisationString = SKY_UK_DEFAULT_TRANSPONDER_POLARISATION;
+            break;
+        }
+      }
+    }
+
+    /// <summary>
+    /// Gets/Sets the default transponder symbol rate
+    /// </summary>
+    public int DefaultTransponderSymbolRate
+    {
+      get
+      {
+        return GetSetting<int>("SkyUKDefaultTransponderSymbolRate", SKY_UK_DEFAULT_TRANSPONDER_SYMBOL_RATE);
+      }
+      set
+      {
+        SetSetting("SkyUKDefaultTransponderSymbolRate", value);
+      }
+    }
+
+    /// <summary>
+    /// Gets/Sets the default transponder inner FEC
+    /// </summary>
+    public string DefaultTransponderInnerFECString
+    {
+      get
+      {
+        return GetSetting<string>("SkyUKDefaultTransponderInnerFEC", SKY_UK_DEFAULT_TRANSPONDER_INNER_FEC);
+      }
+      set
+      {
+        SetSetting("SkyUKDefaultTransponderInnerFEC", value);
+      }
+    }
+
+    /// <summary>
+    /// Gets the default transponder inner FEC
+    /// </summary>
+    public BinaryConvolutionCodeRate DefaultTransponderInnerFEC
+    {
+      get
+      {
+        switch (DefaultTransponderInnerFECString)
+        {
+          case "1/2":
+            return BinaryConvolutionCodeRate.Rate1_2;
+          case "1/3":
+            return BinaryConvolutionCodeRate.Rate1_3;
+          case "1/4":
+            return BinaryConvolutionCodeRate.Rate1_4;
+          case "2/3":
+            return BinaryConvolutionCodeRate.Rate2_3;
+          case "2/5":
+            return BinaryConvolutionCodeRate.Rate2_5;
+          case "3/4":
+            return BinaryConvolutionCodeRate.Rate3_4;
+          case "3/5":
+            return BinaryConvolutionCodeRate.Rate3_5;
+          case "4/5":
+            return BinaryConvolutionCodeRate.Rate4_5;
+          case "5/11":
+            return BinaryConvolutionCodeRate.Rate5_11;
+          case "5/6":
+            return BinaryConvolutionCodeRate.Rate5_6;
+          case "7/8":
+            return BinaryConvolutionCodeRate.Rate7_8;
+          case "8/9":
+            return BinaryConvolutionCodeRate.Rate8_9;
+          case "9/10":
+            return BinaryConvolutionCodeRate.Rate9_10;
+        }
+
+        return BinaryConvolutionCodeRate.Rate2_3;
+      }
+      set
+      {
+        switch (value)
+        {
+          case BinaryConvolutionCodeRate.Rate1_2:
+            DefaultTransponderInnerFECString = "1/2";
+            break;
+          case BinaryConvolutionCodeRate.Rate1_3:
+            DefaultTransponderInnerFECString = "1/3";
+            break;
+          case BinaryConvolutionCodeRate.Rate1_4:
+            DefaultTransponderInnerFECString = "1/4";
+            break;
+          case BinaryConvolutionCodeRate.Rate2_3:
+            DefaultTransponderInnerFECString = "2/3";
+            break;
+          case BinaryConvolutionCodeRate.Rate2_5:
+            DefaultTransponderInnerFECString = "2/5";
+            break;
+          case BinaryConvolutionCodeRate.Rate3_4:
+            DefaultTransponderInnerFECString = "3/4";
+            break;
+          case BinaryConvolutionCodeRate.Rate3_5:
+            DefaultTransponderInnerFECString = "3/5";
+            break;
+          case BinaryConvolutionCodeRate.Rate4_5:
+            DefaultTransponderInnerFECString = "4/5";
+            break;
+          case BinaryConvolutionCodeRate.Rate5_11:
+            DefaultTransponderInnerFECString = "5/11";
+            break;
+          case BinaryConvolutionCodeRate.Rate5_6:
+            DefaultTransponderInnerFECString = "5/6";
+            break;
+          case BinaryConvolutionCodeRate.Rate6_7:
+            DefaultTransponderInnerFECString = "6/7";
+            break;
+          case BinaryConvolutionCodeRate.Rate7_8:
+            DefaultTransponderInnerFECString = "7/8";
+            break;
+          case BinaryConvolutionCodeRate.Rate8_9:
+            DefaultTransponderInnerFECString = "8/9";
+            break;
+          case BinaryConvolutionCodeRate.Rate9_10:
+            DefaultTransponderInnerFECString = "9/10";
+            break;
+
+          default:
+            DefaultTransponderInnerFECString = "2/3";
+            break;
+        }
+      }
+    }
+
+    /// <summary>
+    /// Gets/Sets the default transponder symbol rate
+    /// </summary>
+    public int NetworkId
+    {
+      get
+      {
+        return GetSetting<int>("SkyUKNetworkId", SKY_UK_DEFAULT_NETWORK_ID);
+      }
+      set
+      {
+        SetSetting("SkyUKNetworkId", value);
+      }
+    }
+
+    #endregion
+
+    #region Methods
+
+    /// <summary>
+    /// Resets the default transponder parameters
+    /// </summary>
+    public void ResetDefaultTransponderParameters()
+    {
+      DefaultTransponderFrequency = SKY_UK_DEFAULT_TRANSPONDER_FREQUENCY;
+      DefaultTransponderPolarisationString = SKY_UK_DEFAULT_TRANSPONDER_POLARISATION;
+      DefaultTransponderSymbolRate = SKY_UK_DEFAULT_TRANSPONDER_SYMBOL_RATE;
+      DefaultTransponderInnerFECString = SKY_UK_DEFAULT_TRANSPONDER_INNER_FEC;
+      NetworkId = SKY_UK_DEFAULT_NETWORK_ID;
+    }
+
+    #endregion
+
+  }
+}
Index: TvEngine3/TVLibrary/TVLibrary/Interfaces/Analyzer/ITsEpgScanner.cs
===================================================================
--- TvEngine3/TVLibrary/TVLibrary/Interfaces/Analyzer/ITsEpgScanner.cs	(revision 27484)
+++ TvEngine3/TVLibrary/TVLibrary/Interfaces/Analyzer/ITsEpgScanner.cs	(working copy)
@@ -186,6 +186,77 @@
     int GetMHWTheme(uint themeId, out IntPtr theme);
 
     /// <summary>
+    /// Starts the sky epg grabber
+    /// Country:
+    /// 1 = UK
+    /// 2 = Italy
+    /// 3 = Australia (Not yet implemented)
+    /// </summary>
+    /// <returns></returns>
+    [PreserveSig]
+    int ActivateSkyEpgGrabber(uint country);
+
+    /// <summary>
+    /// Gets if the Sky epg is active
+    /// </summary>
+    /// <param name="active"></param>
+    /// <returns></returns>
+    [PreserveSig]
+    int IsSkyEpgGrabberActive(ref byte active);
+
+    /// <summary>
+    /// Gets if the Sky epg is ready to be retrieved from tswriter
+    /// </summary>
+    /// <param name="ready"></param>
+    /// <returns></returns>
+    [PreserveSig]
+    int IsSkyEpgReady(ref byte ready);
+
+    /// <summary>
+    /// Gets if the Sky epg grabbing was aborted
+    /// </summary>
+    /// <param name="aborted"></param>
+    /// <returns></returns>
+    [PreserveSig]
+    int HasSkyEpgAborted(ref byte aborted);
+
+    /// <summary>
+    /// Resets the epg retrieval iterators
+    /// </summary>
+    /// <returns></returns>
+    [PreserveSig]
+    int ResetSkyEpgRetrieval();
+
+    /// <summary>
+    /// Gets the next Sky epg channel
+    /// </summary>
+    /// <param name="atEndChannel"></param>
+    /// <param name="channelId"></param>
+    /// <param name="networkId"></param>
+    /// <param name="transportId"></param>
+    /// <param name="serviceId"></param>
+    /// <returns></returns>
+    [PreserveSig]
+    int GetNextSkyEpgChannel(ref byte atEndChannel, ref ushort channelId, ref ushort networkId, ref ushort transportId, ref ushort serviceId);
+
+    /// <summary>
+    /// Gets the next Sky channel epg event
+    /// </summary>
+    /// <param name="atEndChannelEvent"></param>
+    /// <param name="eventId"></param>
+    /// <param name="mjdStart"></param>
+    /// <param name="startTime"></param>
+    /// <param name="duration"></param>
+    /// <param name="title"></param>
+    /// <param name="summary"></param>
+    /// <param name="theme"></param>
+    /// <param name="seriesId"></param>
+    /// <param name="seriesTermination"></param>
+    /// <returns></returns>
+    [PreserveSig]
+    int GetNextSkyEpgChannelEvent(ref byte atEndChannelEvent, ref ushort eventId, ref ushort mjdStart, ref uint startTime, ref uint duration, out IntPtr title, out IntPtr summary, out IntPtr theme, ref ushort seriesId, ref byte seriesTermination);
+
+    /// <summary>
     /// Resets this MHW grabber.
     /// </summary>
     /// <returns></returns>
Index: TvEngine3/TVLibrary/TVLibrary/TVLibrary.csproj
===================================================================
--- TvEngine3/TVLibrary/TVLibrary/TVLibrary.csproj	(revision 27484)
+++ TvEngine3/TVLibrary/TVLibrary/TVLibrary.csproj	(working copy)
@@ -2,7 +2,7 @@
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>9.0.30729</ProductVersion>
+    <ProductVersion>9.0.21022</ProductVersion>
     <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{59C2EBC8-0FEA-4B2E-B5D1-476347332331}</ProjectGuid>
     <OutputType>Library</OutputType>
@@ -152,6 +152,9 @@
     <Compile Include="Implementations\Helper\FilterGraphTools.cs" />
     <Compile Include="Implementations\Helper\GraphState.cs" />
     <Compile Include="Implementations\Helper\HResult.cs" />
+    <Compile Include="Implementations\Helper\Providers\SkyItaly.cs" />
+    <Compile Include="Implementations\Helper\Providers\Provider.cs" />
+    <Compile Include="Implementations\Helper\Providers\SkyUK.cs" />
     <Compile Include="Implementations\Helper\Release.cs" />
     <Compile Include="Implementations\Helper\SidHelper.cs" />
     <Compile Include="Implementations\Hybrid\HybridCardGroup.cs" />
Index: TvEngine3/TVLibrary/TvPlugin/TvPlugin/TvGuideBase.cs
===================================================================
--- TvEngine3/TVLibrary/TvPlugin/TvPlugin/TvGuideBase.cs	(revision 27484)
+++ TvEngine3/TVLibrary/TvPlugin/TvPlugin/TvGuideBase.cs	(working copy)
@@ -128,6 +128,7 @@
     private long _currentStartTime = 0;
     private long _currentEndTime = 0;
     private Program _currentProgram = null;
+    private static Schedule currentSchedule;
     private bool _needUpdate = false;
     private DateTime m_dtStartTime = DateTime.Now;
     private ArrayList _colorList = new ArrayList();
@@ -169,6 +170,10 @@
     private GUIButton3PartControl _programNotRunningTemplate;
     private GUIButton3PartControl _programRunningTemplate;
     
+
+    private bool _useQuickRecordMenu = false;
+    private readonly List<ScheduleRecordingType> _quickRecordMenuSchedules = new List<ScheduleRecordingType>();
+    
     // current minimum/maximum indexes
     //private int MaxXIndex; // means rows here (channels)
     private int MinYIndex; // means cols here (programs/time)
@@ -252,6 +257,57 @@
         _hdtvProgramText = xmlreader.GetValueAsString("mytv", "hdtvProgramText", "(HDTV)");
         _guideContinuousScroll = xmlreader.GetValueAsBool("mytv", "continuousScrollGuide", false);
         _loopDelay = xmlreader.GetValueAsInt("gui", "listLoopDelay", 0);
+
+        //  Load the quick record menu settings
+        _useQuickRecordMenu = xmlreader.GetValueAsBool("mytv", "usequickrecordmenu", false);
+
+        string[] selectedQuickRecordSchedules = xmlreader.GetValueAsString("mytv", "selectedquickrecordschedules", string.Empty).Split(',');
+
+          //  Check loaded items
+        foreach (string selectedSchedule in selectedQuickRecordSchedules)
+        {
+          ScheduleRecordingType schedule = (ScheduleRecordingType)(-1);
+
+          switch (selectedSchedule)
+          {
+            case "Once":
+              schedule = ScheduleRecordingType.Once;
+              break;
+            case "Daily":
+              schedule = ScheduleRecordingType.Daily;
+              break;
+            case "Weekly":
+              schedule = ScheduleRecordingType.Weekly;
+              break;
+            case "EveryTimeOnThisChannel":
+              schedule = ScheduleRecordingType.EveryTimeOnThisChannel;
+              break;
+            case "EveryTimeOnEveryChannel":
+              schedule = ScheduleRecordingType.EveryTimeOnEveryChannel;
+              break;
+            case "Weekends":
+              schedule = ScheduleRecordingType.Weekends;
+              break;
+            case "WorkingDays":
+              schedule = ScheduleRecordingType.WorkingDays;
+              break;
+            case "WeeklyEveryTimeOnThisChannel":
+              schedule = ScheduleRecordingType.WeeklyEveryTimeOnThisChannel;
+              break;
+            case "SeriesLink":
+              schedule = ScheduleRecordingType.SeriesLink;
+              break;
+          }
+
+          if (schedule != (ScheduleRecordingType)(-1) && !_quickRecordMenuSchedules.Contains(schedule))
+            _quickRecordMenuSchedules.Add(schedule);
+
+        }
+
+        //  If there are no schedules listed, never use the quick record menu
+        if (_quickRecordMenuSchedules.Count == 0)
+          _useQuickRecordMenu = false;
+
       }
       _useNewRecordingButtonColor =
         Utils.FileExistsInCache(Path.Combine(GUIGraphicsContext.Skin, @"media\tvguide_recButton_Focus_middle.png"));
@@ -3821,10 +3877,129 @@
           }
         }
       }
+
+      //  Else if we want to use the quick record menu
+      else if (_useQuickRecordMenu)
+      {
+        //  Open the quick record menu
+        GUIDialogMenu quickRecordMenu = (GUIDialogMenu)GUIWindowManager.GetWindow((int)Window.WINDOW_DIALOG_MENU);
+        if (quickRecordMenu == null)
+        {
+          ShowProgramInfo();
+          return;
+        }
+
+        quickRecordMenu.Reset();
+        quickRecordMenu.SetHeading(GUILocalizeStrings.Get(200093)); //200093=Quick record
+
+        //  If the program has series link information (Sky UK/IT/AU / FreeSat)
+        bool seriesLinkAvailable = (_currentProgram.SeriesId != 0);
+
+        //  Maintain a lookup so we know which schedule the user selected
+        Dictionary<int, ScheduleRecordingType> scheduleIndexLookup = new Dictionary<int, ScheduleRecordingType>();
+
+        int currentIndex = 0;
+
+        //  Loop through all schedules to be added
+        foreach (ScheduleRecordingType schedule in _quickRecordMenuSchedules)
+        {
+          string scheduleDescription = string.Empty;
+
+          switch (schedule)
+          {
+            case ScheduleRecordingType.Daily:
+              //  Record every day at this time
+              scheduleDescription = GUILocalizeStrings.Get(615);
+              break;
+
+            case ScheduleRecordingType.EveryTimeOnEveryChannel:
+              //  Record every time on every channel
+              scheduleDescription = GUILocalizeStrings.Get(613);
+              break;
+
+            case ScheduleRecordingType.EveryTimeOnThisChannel:
+              //  Record every time on this channel
+              scheduleDescription = GUILocalizeStrings.Get(612);
+              break;
+
+            case ScheduleRecordingType.Once:
+              //  Record once
+              scheduleDescription = GUILocalizeStrings.Get(611);
+              break;
+
+            case ScheduleRecordingType.SeriesLink:
+              //  Record series
+              scheduleDescription = GUILocalizeStrings.Get(200092);
+              break;
+
+            case ScheduleRecordingType.Weekends:
+              //  Record weekends
+              scheduleDescription = GUILocalizeStrings.Get(1051);
+              break;
+
+            case ScheduleRecordingType.Weekly:
+              //  Record every week at this time
+              scheduleDescription = GUILocalizeStrings.Get(614);
+              break;
+
+            case ScheduleRecordingType.WeeklyEveryTimeOnThisChannel:
+              //  Weekly on this channel
+              scheduleDescription = GUILocalizeStrings.Get(990000);
+              break;
+
+            case ScheduleRecordingType.WorkingDays:
+              //  Record weekdays
+              scheduleDescription = GUILocalizeStrings.Get(672);
+              break;
+
+          }
+
+          //  If valid schedule
+          if (scheduleDescription != string.Empty)
+          {
+            //  If series link, check it is available and skip of not
+            if (schedule == ScheduleRecordingType.SeriesLink && !seriesLinkAvailable)
+              continue;
+
+            quickRecordMenu.Add(scheduleDescription);
+
+            scheduleIndexLookup.Add(currentIndex, schedule);
+
+            currentIndex++;
+          }
+
+        }
+
+        //  Programme info
+        quickRecordMenu.AddLocalizedString(200094);
+
+        quickRecordMenu.DoModal(GetID);
+        int selectedIndex = quickRecordMenu.SelectedLabel;
+
+        //  If none selected
+        if (selectedIndex == -1)
+          return;
+
+        //  Get the selected schedule from the lookup
+        //  If it is not there, the user has chosen to go to the programme information window
+        ScheduleRecordingType selectedSchedule;
+        if (!scheduleIndexLookup.TryGetValue(selectedIndex, out selectedSchedule))
+        {
+          ShowProgramInfo();
+          return;
+        }
+
+        //  Else try and create the schedule
+        TVProgramInfo.CreateProgram(_currentProgram, (int)selectedSchedule, GetID);
+
+        //  Refresh the gui
+        Update(true);
+
+      }
+
+      //  Else show the program info screen
       else
-      {
         ShowProgramInfo();
-      }
     }
 
     /// <summary>
Index: TvEngine3/TVLibrary/TvPlugin/TvPlugin/TvPlugin.csproj
===================================================================
--- TvEngine3/TVLibrary/TvPlugin/TvPlugin/TvPlugin.csproj	(revision 27484)
+++ TvEngine3/TVLibrary/TvPlugin/TvPlugin/TvPlugin.csproj	(working copy)
@@ -2,7 +2,7 @@
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>9.0.30729</ProductVersion>
+    <ProductVersion>9.0.21022</ProductVersion>
     <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{1526A789-1DE2-4A8B-AA4B-5382A617C4F8}</ProjectGuid>
     <OutputType>Library</OutputType>
Index: TvEngine3/TVLibrary/TvPlugin/TvPlugin/TVProgramInfo.cs
===================================================================
--- TvEngine3/TVLibrary/TvPlugin/TvPlugin/TVProgramInfo.cs	(revision 27484)
+++ TvEngine3/TVLibrary/TvPlugin/TvPlugin/TVProgramInfo.cs	(working copy)
@@ -328,6 +328,9 @@
         {
           CurrentProgram = new Program(value.IdChannel, value.StartTime, value.EndTime, value.ProgramName, "",
                                        "", Program.ProgramState.None, DateTime.MinValue, "", "", "", "", 0, "", 0);
+
+          CurrentProgram.SeriesId = value.SeriesId;
+
         }        
       }
     }
@@ -336,7 +339,7 @@
 
     #region Static methods
 
-    private static string GetRecordingDateTime(Schedule rec)
+    internal static string GetRecordingDateTime(Schedule rec)
     {
       return String.Format("{0} {1} - {2}",
                            Utils.GetShortDayString(rec.StartTime),
@@ -344,7 +347,7 @@
                            rec.EndTime.ToString("t", CultureInfo.CurrentCulture.DateTimeFormat));
     }
 
-    private static bool IsRecordingProgram(Program program, out Schedule recordingSchedule,
+    internal static bool IsRecordingProgram(Program program, out Schedule recordingSchedule,
                                            bool filterCanceledRecordings)
     {
       recordingSchedule = null;
@@ -1025,11 +1028,11 @@
       Schedule recordingSchedule;
       if (!anyUpcomingEpisodesRecording && currentSchedule != null)
       {
-        CancelProgram(program, currentSchedule);
+        CancelProgram(program, currentSchedule, GetID);
       }
       else if (IsRecordingProgram(program, out recordingSchedule, true)) // check if schedule is already existing
       {
-        CancelProgram(program, recordingSchedule);
+        CancelProgram(program, recordingSchedule, GetID);
       }
       else
       {
@@ -1046,18 +1049,18 @@
           }
           else
           {
-            CreateProgram(program, (int)ScheduleRecordingType.Once);
+            CreateProgram(program, (int)ScheduleRecordingType.Once, GetID);
           }
         }
         else
         {
-          CreateProgram(program, (int)ScheduleRecordingType.Once);
+          CreateProgram(program, (int)ScheduleRecordingType.Once, GetID);
         }
       }
       Update();
     }
 
-    private void CancelProgram(Program program, Schedule schedule)
+    internal static void CancelProgram(Program program, Schedule schedule, int windowId)
     {
       Log.Debug("TVProgammInfo.CancelProgram - programm = {0}", program.ToString());
       Log.Debug("                            - schedule = {0}", schedule.ToString());
@@ -1095,7 +1098,7 @@
           dlg.AddLocalizedString(981); //Cancel this show
         }
         dlg.AddLocalizedString(982); //Delete this entire schedule
-        dlg.DoModal(GetID);
+        dlg.DoModal(windowId);
         if (dlg.SelectedLabel == -1)
         {
           return;
@@ -1129,13 +1132,13 @@
       }
     }
 
-    private void ResetCurrentScheduleAndProgram()
+    private static void ResetCurrentScheduleAndProgram()
     {
       currentProgram = initialProgram;
       currentSchedule = null;
     }
 
-    private void ResetCurrentScheduleAndProgram(Schedule schedule)
+    private static void ResetCurrentScheduleAndProgram(Schedule schedule)
     {
       if (
         currentSchedule == null ||
@@ -1148,7 +1151,7 @@
       }
     }
 
-    private void CreateProgram(Program program, int scheduleType)
+    internal static void CreateProgram(Program program, int scheduleType, int windowId)
     {
       Log.Debug("TVProgramInfo.CreateProgram: program = {0}", program.ToString());
       Schedule schedule;
@@ -1170,6 +1173,10 @@
           schedule.PreRecordInterval = saveSchedule.PreRecordInterval;
           schedule.PostRecordInterval = saveSchedule.PostRecordInterval;
           schedule.ScheduleType = (int)ScheduleRecordingType.Once; // needed for layer.GetConflictingSchedules(...)
+
+          //  If series link
+          if (scheduleType == (int)ScheduleRecordingType.SeriesLink)
+            schedule.SeriesId = program.SeriesId;
         }
       }
       else
@@ -1180,6 +1187,10 @@
         schedule.PreRecordInterval = Int32.Parse(layer.GetSetting("preRecordInterval", "5").Value);
         schedule.PostRecordInterval = Int32.Parse(layer.GetSetting("postRecordInterval", "5").Value);
         schedule.ScheduleType = scheduleType;
+
+        //  If series link
+        if (scheduleType == (int)ScheduleRecordingType.SeriesLink)
+          schedule.SeriesId = program.SeriesId;
       }
 
       // check if this program is conflicting with any other already scheduled recording
@@ -1214,7 +1225,7 @@
             dlg.AddConflictRecording(item);
           }
           dlg.ConflictingEpisodes = (scheduleType != (int)ScheduleRecordingType.Once);
-          dlg.DoModal(GetID);
+          dlg.DoModal(windowId);
           switch (dlg.SelectedLabel)
           {
             case 0: // Skip new Recording
@@ -1232,7 +1243,7 @@
                                 Program.ProgramState.None,
                                 DateTime.MinValue, string.Empty, string.Empty, string.Empty, string.Empty, -1,
                                 string.Empty, -1);
-                  CancelProgram(prog, Schedule.Retrieve(conflict.IdSchedule));
+                  CancelProgram(prog, Schedule.Retrieve(conflict.IdSchedule), windowId);
                 }
                 break;
               }
@@ -1313,6 +1324,8 @@
       {
         dlg.Reset();
         dlg.SetHeading(GUILocalizeStrings.Get(616)); //616=Select Schedule type
+
+
         //610=None
         //611=Record once
         //612=Record everytime on this channel
@@ -1327,6 +1340,14 @@
         dlg.Add(GUILocalizeStrings.Get(WeekEndTool.GetText(DayType.Record_WeekendDays)));
         dlg.AddLocalizedString(990000); // 990000=Weekly everytime on this channel
 
+        //  If the program has series link information (Sky UK/IT/AU / FreeSat)
+        bool seriesLinkAvailable = (CurrentProgram.SeriesId != 0);
+        if (seriesLinkAvailable)
+        {
+          //  200092=Series Link
+          dlg.AddLocalizedString(200092);
+        }
+
         dlg.DoModal(GetID);
         if (dlg.SelectedLabel == -1)
         {
@@ -1334,6 +1355,7 @@
         }
 
         int scheduleType = (int)ScheduleRecordingType.Once;
+
         switch (dlg.SelectedLabel)
         {
           case 0: //once
@@ -1360,9 +1382,14 @@
           case 7://Weekly everytime, this channel
             scheduleType = (int)ScheduleRecordingType.WeeklyEveryTimeOnThisChannel;
             break;
+          case 8: //  Series Link
+            scheduleType = (int)ScheduleRecordingType.SeriesLink;
+            break;
         }
-        CreateProgram(CurrentProgram, scheduleType);
+        
 
+        CreateProgram(CurrentProgram, scheduleType, GetID);
+
         if (scheduleType == (int)ScheduleRecordingType.Once)
         {
           //check if this program is interrupted (for example by a news bulletin)
@@ -1388,7 +1415,7 @@
                 dlgYesNo.DoModal(GetID);
                 if (dlgYesNo.IsConfirmed)
                 {
-                  CreateProgram(nextNext, scheduleType);
+                  CreateProgram(nextNext, scheduleType, GetID);
                   Update();
                 }
               }
Index: TvEngine3/TVLibrary/TvPlugin/TvPlugin/TVScheduler.cs
===================================================================
--- TvEngine3/TVLibrary/TvPlugin/TvPlugin/TVScheduler.cs	(revision 27484)
+++ TvEngine3/TVLibrary/TvPlugin/TvPlugin/TVScheduler.cs	(working copy)
@@ -776,9 +776,13 @@
                  default:
                      day = GUILocalizeStrings.Get(17);
                      break;
-          }
+            }
              item.Label2 = GUILocalizeStrings.Get(990001, new object[] { day, rec.ReferencedChannel().DisplayName });
-             break;              
+             break;
+
+           case (int)ScheduleRecordingType.SeriesLink:
+             item.Label2 = GUILocalizeStrings.Get(200095, new object[] { rec.ReferencedChannel().DisplayName });
+             break;
         }
         }
         else
Index: TvEngine3/TVLibrary/TvPlugin/TvPlugin/TVSearch.cs
===================================================================
--- TvEngine3/TVLibrary/TvPlugin/TvPlugin/TVSearch.cs	(revision 27484)
+++ TvEngine3/TVLibrary/TvPlugin/TvPlugin/TVSearch.cs	(working copy)
@@ -1173,6 +1173,12 @@
         dlg.Add(GUILocalizeStrings.Get(WeekEndTool.GetText(DayType.Record_WeekendDays)));
         dlg.Add(GUILocalizeStrings.Get(990000));  // 990000=Weekly everytime on this channel
 
+        //  If the program has series link information (Sky UK/IT/AU / FreeSat)
+        bool seriesLinkAvailable = (program.SeriesId != 0);
+
+        if (seriesLinkAvailable)
+          dlg.Add(GUILocalizeStrings.Get(200092));  // 200092=Series link
+
         dlg.DoModal(GetID);
         if (dlg.SelectedLabel == -1)
         {
@@ -1232,6 +1238,13 @@
           case 8://Weekly everytime, this channel
             rec.ScheduleType = (int)ScheduleRecordingType.WeeklyEveryTimeOnThisChannel;
             break;
+          case 9://Series link
+            rec.ScheduleType = (int)ScheduleRecordingType.SeriesLink;
+            
+            //  Set series id
+            rec.SeriesId = program.SeriesId;
+
+            break;
         }
         rec.Persist();
         server.OnNewSchedule();
Index: TvEngine3/TVLibrary/TvService/Epg/EpgCard.cs
===================================================================
--- TvEngine3/TVLibrary/TvService/Epg/EpgCard.cs	(revision 27484)
+++ TvEngine3/TVLibrary/TvService/Epg/EpgCard.cs	(working copy)
@@ -28,6 +28,8 @@
 using TvLibrary.Epg;
 using TvEngine.Events;
 using System.Threading;
+using DirectShowLib.BDA;
+using TvLibrary.Implementations.Helper.Providers;
 
 namespace TvService
 {
@@ -72,6 +74,11 @@
     private IUser _user;
     private readonly EpgDBUpdater _dbUpdater;
 
+    /// <summary>
+    /// Mode (normal or provider - Sky is grabbed by tuning a transponder rather than a specific channel)
+    /// </summary>
+    private eEPGGrabMode _epgGrabMode = eEPGGrabMode.Normal;
+
     #endregion
 
     #region ctor
@@ -129,6 +136,17 @@
       get { return (_state != EpgState.Idle); }
     }
 
+    /// <summary>
+    /// Gets the EPG grab mode
+    /// </summary>
+    public sealed override BaseEpgGrabber.eEPGGrabMode EPGGrabMode
+    {
+      get
+      {
+        return _epgGrabMode;
+      }
+    }
+
     #endregion
 
     #region epg callback
@@ -192,14 +210,18 @@
         {
           //no epg found for this transponder
           Log.Epg("Epg: card:{0} no epg found", _user.CardId);
-          _currentTransponder.InUse = false;
-          _currentTransponder.OnTimeOut();
 
+          //  Null if sky epg grabbing
+          if (_currentTransponder != null)
+          {
+            _currentTransponder.InUse = false;
+            _currentTransponder.OnTimeOut();
+          }
+
           _state = EpgState.Idle;
           _tvController.StopGrabbingEpg(_user);
           _tvController.PauseCard(_user);
           _user.CardId = -1;
-          _currentTransponder.InUse = false;
           return 0;
         }
 
@@ -238,6 +260,9 @@
       _currentTransponder = TransponderList.Instance.CurrentTransponder;
       Channel channel = _currentTransponder.CurrentChannel;
 
+      //  Normal grab (not by transponder)
+      _epgGrabMode = eEPGGrabMode.Normal;
+
       Log.Epg("EpgCard: grab epg on card: #{0} transponder: #{1} ch:{2} ", _card.IdCard,
               TransponderList.Instance.CurrentIndex, channel.DisplayName);
 
@@ -278,8 +303,247 @@
       _isRunning = false;
     }
 
+    /// <summary>
+    /// Checks if it is time to grab the EPG for any specific providers.  Returns true if grab started, or false otherwise
+    /// </summary>
+    public bool GrabProviderEPG(int reGrabAfterMinutes)
+    {
+      try
+      {
+        CardType type = _tvController.Type(Card.IdCard);
+
+        //  If satellite card
+        if (type == CardType.DvbS)
+        {
+          if (GrabSkyUKEPG(reGrabAfterMinutes))
+            return true;
+
+          if (GrabSkyItalyEPG(reGrabAfterMinutes))
+            return true;
+        }
+      }
+      catch (Exception ex)
+      {
+        //  Ensure normal mode is set back and log error
+        _epgGrabMode = eEPGGrabMode.Normal;
+        Log.Error("Exception detected in GrabProviderEpg():\r\n\r\n" + ex.ToString());
+      }
+
+      return false;
+    }
+
+    #region Provider EPGs
+
+    /// <summary>
+    /// Checks if the EPG for Sky UK should be grabbed and starts it if so.  Returns if grabbing was started
+    /// </summary>
+    /// <returns></returns>
+    private bool GrabSkyUKEPG(int reGrabAfterMinutes)
+    {
+      //  If we are not set to grab the Sky UK Epg, return here
+      if (!SkyUK.Instance.EPGGrabbingEnabled)
+        return false;
+
+      //  Get the last grab time
+      DateTime lastEpgGrabTime = SkyUK.Instance.LastEPGGrabTime;
+
+      TimeSpan timeSinceLastGrab = DateTime.Now - lastEpgGrabTime;
+
+      //  If the time since last grab does not reach the threshold, return
+      if (timeSinceLastGrab.TotalMinutes < reGrabAfterMinutes)
+        return false;
+
+      Log.Epg("Initializing grab for Sky UK");
+
+      //  Find all channels on the default transponder
+      IList<TuningDetail> defaultTransponderChannels = TuningDetail.Find(SkyUK.Instance.DefaultTransponderFrequency, 500, (int)SkyUK.Instance.DefaultTransponderPolarisation, (int)SkyUK.Instance.DefaultTransponderInnerFEC, SkyUK.Instance.DefaultTransponderSymbolRate, SkyUK.Instance.NetworkId);
+
+      //  Check at leat 1 channel was found for the default transponder
+      if (defaultTransponderChannels == null || defaultTransponderChannels.Count == 0)
+      {
+        Log.Epg("Error cannot start EPG grabbing for Sky UK as no channels could be found for the default transponder");
+
+        //  Postpone until next grab
+        SkyUK.Instance.LastEPGGrabTime = DateTime.Now;
+
+        return false;
+      }
+
+      Log.Epg("There are " + defaultTransponderChannels.Count.ToString() + " known channels on the default transponder");
+
+      TvBusinessLayer layer = new TvBusinessLayer();
+
+      //  Loop through all channels on the default transponder until epg grabbing is started successfully
+      foreach (TuningDetail currentChannelTuning in defaultTransponderChannels)
+      {
+        Channel referencedChannel = currentChannelTuning.ReferencedChannel();
+
+        if (referencedChannel == null)
+          continue;
+        
+        //  Check the card can tune this channel
+        if (!Card.canTuneTvChannel(referencedChannel.IdChannel))
+        {
+          Log.Epg("Card " + Card.IdCard + " cannot tune '" + referencedChannel.DisplayName + "', trying next");
+          continue;
+        }
+
+        Log.Epg("Tuning to '" + referencedChannel.DisplayName + "' to grab EPG for Sky UK");
+
+        //  Set idle
+        _state = EpgState.Idle;
+
+        _isRunning = true;
+        _user = new User("Sky UK", false, -1);
+
+        //  Sky is grabbed by tuning the default transponder rather than a specific channel
+        _epgGrabMode = eEPGGrabMode.SkyUK;
+
+        IChannel channelTuning = layer.GetTuningChannelByType(referencedChannel, currentChannelTuning.ChannelType);
+
+        //  Try to grab and update last grab time if successful
+        if (GrabEpgForChannel(referencedChannel, channelTuning, _card))
+        {
+          //  Succeeded
+          _state = EpgState.Grabbing;
+          _grabStartTime = DateTime.Now;
+
+          try
+          {
+            _epgTimer.Enabled = true;
+          }
+          catch (ObjectDisposedException)
+          {
+            return false;
+          }
+
+          Log.Epg("EPG grab for Sky UK started successfully");
+
+          return true;
+        }
+        else
+        {
+          _epgGrabMode = eEPGGrabMode.Normal;
+
+          Log.Epg("Failed to start grabbing EPG for Sky UK on channel '" + referencedChannel.DisplayName + "'.  Trying next");
+        }
+      }
+
+      Log.Epg("Failed to start grabbing EPG for Sky UK on any channel in transponder list");
+
+      //  Postpone until next grab
+      SkyUK.Instance.LastEPGGrabTime = DateTime.Now;
+
+      return false;
+    }
+
+    /// <summary>
+    /// Checks if the EPG for Sky Italy should be grabbed and starts it if so.  Returns if grabbing was started
+    /// </summary>
+    /// <returns></returns>
+    private bool GrabSkyItalyEPG(int reGrabAfterMinutes)
+    {
+      //  If we are not set to grab the Sky Italy Epg, return here
+      if (!SkyItaly.Instance.EPGGrabbingEnabled)
+        return false;
+
+      //  Get the last grab time
+      DateTime lastEpgGrabTime = SkyItaly.Instance.LastEPGGrabTime;
+
+      TimeSpan timeSinceLastGrab = DateTime.Now - lastEpgGrabTime;
+
+      //  If the time since last grab does not reach the threshold, return
+      if (timeSinceLastGrab.TotalMinutes < reGrabAfterMinutes)
+        return false;
+
+      Log.Epg("Initializing grab for Sky Italy");
+
+      //  Find all channels on the default transponder
+      IList<TuningDetail> defaultTransponderChannels = TuningDetail.Find(SkyItaly.Instance.DefaultTransponderFrequency, 500, (int)SkyItaly.Instance.DefaultTransponderPolarisation, (int)SkyItaly.Instance.DefaultTransponderInnerFEC, SkyItaly.Instance.DefaultTransponderSymbolRate, SkyItaly.Instance.NetworkId);
+
+      //  Check at leat 1 channel was found for the default transponder
+      if (defaultTransponderChannels == null || defaultTransponderChannels.Count == 0)
+      {
+        Log.Epg("Error cannot start EPG grabbing for Sky Italy as no channels could be found for the default transponder");
+
+        //  Postpone until next grab
+        SkyItaly.Instance.LastEPGGrabTime = DateTime.Now;
+
+        return false;
+      }
+
+      Log.Epg("There are " + defaultTransponderChannels.Count.ToString() + " known channels on the default transponder");
+
+      TvBusinessLayer layer = new TvBusinessLayer();
+
+      //  Loop through all channels on the default transponder until epg grabbing is started successfully
+      foreach (TuningDetail currentChannelTuning in defaultTransponderChannels)
+      {
+        Channel referencedChannel = currentChannelTuning.ReferencedChannel();
+
+        if (referencedChannel == null)
+          continue;
+
+        //  Check the card can tune this channel
+        if (!Card.canTuneTvChannel(referencedChannel.IdChannel))
+        {
+          Log.Epg("Card " + Card.IdCard + " cannot tune '" + referencedChannel.DisplayName + "', trying next");
+          continue;
+        }
+
+        Log.Epg("Tuning to '" + referencedChannel.DisplayName + "' to grab EPG for Sky Italy");
+
+        //  Set idle
+        _state = EpgState.Idle;
+
+        _isRunning = true;
+        _user = new User("Sky Italy", false, -1);
+
+        //  Sky is grabbed by tuning the default transponder rather than a specific channel
+        _epgGrabMode = eEPGGrabMode.SkyItaly;
+
+        IChannel channelTuning = layer.GetTuningChannelByType(referencedChannel, currentChannelTuning.ChannelType);
+
+        //  Try to grab and update last grab time if successful
+        if (GrabEpgForChannel(referencedChannel, channelTuning, _card))
+        {
+          //  Succeeded
+          _state = EpgState.Grabbing;
+          _grabStartTime = DateTime.Now;
+
+          try
+          {
+            _epgTimer.Enabled = true;
+          }
+          catch (ObjectDisposedException)
+          {
+            return false;
+          }
+
+          Log.Epg("EPG grab for Sky Italy started successfully");
+
+          return true;
+        }
+        else
+        {
+          _epgGrabMode = eEPGGrabMode.Normal;
+
+          Log.Epg("Failed to start grabbing EPG for Sky Italy on channel '" + referencedChannel.DisplayName + "'.  Trying next");
+        }
+      }
+
+      Log.Epg("Failed to start grabbing EPG for Sky Italy on any channel in transponder list");
+
+      //  Postpone until next grab
+      SkyItaly.Instance.LastEPGGrabTime = DateTime.Now;
+
+      return false;
+    }
+
     #endregion
 
+    #endregion
+
     #region private members
 
     /// <summary>
@@ -637,12 +901,15 @@
       //if card is not idle anymore we return
       if (IsCardIdle(_user) == false)
       {
-        _currentTransponder.InUse = false;
+        if (_epgGrabMode == eEPGGrabMode.Normal)
+          _currentTransponder.InUse = false;
+
         return;
       }
       Log.Epg("Epg: card:{0} Updating database with new programs", _user.CardId);
       bool timeOut = false;
       _dbUpdater.ReloadConfig();
+
       try
       {
         foreach (EpgChannel epgChannel in _epg)
@@ -671,7 +938,8 @@
       }
       finally
       {
-        if (timeOut == false)
+
+        if (timeOut == false && _epgGrabMode == eEPGGrabMode.Normal && _currentTransponder != null)
         {
           _currentTransponder.OnTimeOut();
         }
@@ -680,7 +948,29 @@
           _tvController.StopGrabbingEpg(_user);
           _tvController.PauseCard(_user);
         }
-        _currentTransponder.InUse = false;
+
+        if (_epgGrabMode == eEPGGrabMode.Normal && _currentTransponder != null)
+          _currentTransponder.InUse = false;
+
+        try
+        {
+          //  If Sky UK grab and a timeout wasn't triggered
+          if (_epgGrabMode == eEPGGrabMode.SkyUK && !timeOut)
+            SkyUK.Instance.LastEPGGrabTime = DateTime.Now;
+
+          //  If Sky Italy grab and a timeout wasn't triggered
+          if (_epgGrabMode == eEPGGrabMode.SkyItaly && !timeOut)
+            SkyItaly.Instance.LastEPGGrabTime = DateTime.Now;
+
+        }
+        catch (Exception ex)
+        {
+          Log.Error("Exception in UpdateDatabaseThread(): " + ex.ToString());
+        }
+
+        //  Ensure set back to normal
+        _epgGrabMode = eEPGGrabMode.Normal;
+
         _state = EpgState.Idle;
         _user.CardId = -1;
         _tvController.Fire(this, new TvServerEventArgs(TvServerEventType.ProgramUpdated));
Index: TvEngine3/TVLibrary/TvService/Epg/EpgGrabber.cs
===================================================================
--- TvEngine3/TVLibrary/TvService/Epg/EpgGrabber.cs	(revision 27484)
+++ TvEngine3/TVLibrary/TvService/Epg/EpgGrabber.cs	(working copy)
@@ -25,6 +25,8 @@
 using TvLibrary.Log;
 using TvLibrary.Interfaces;
 using System.Threading;
+using TvLibrary.Implementations;
+using TvLibrary.Implementations.Helper.Providers;
 
 namespace TvService
 {
@@ -114,12 +116,20 @@
       {
         _epgReGrabAfter = 240;
       }
+
+      bool providerEPGGrabbingEnabled = Provider.Instance.ProviderEPGGrabbingEnabled;
+
       TransponderList.Instance.RefreshTransponders();
-      if (TransponderList.Instance.Count == 0)
+      if (TransponderList.Instance.Count == 0 && !providerEPGGrabbingEnabled)
       {
         return;
       }
-      Log.Epg("EPG: grabber initialized for {0} transponders..", TransponderList.Instance.Count);
+      if (TransponderList.Instance.Count >= 1)
+        Log.Epg("EPG: grabber initialized for {0} transponders..", TransponderList.Instance.Count);
+
+      if (providerEPGGrabbingEnabled)
+        Log.Epg("EPG: grabber initialized for configured providers");
+
       _isRunning = true;
       IList<Card> cards = Card.ListAll();
 
@@ -261,6 +271,10 @@
       if (type == CardType.Analog || type == CardType.RadioWebStream)
         return;
 
+      //  Grab all providers, return if one was started successfully
+      if (epgCard.GrabProviderEPG(_epgReGrabAfter))
+        return;
+
       while (TransponderList.Instance.GetNextTransponder() != null)
       {
         //skip transponders which are in use
Index: TvEngine3/TVLibrary/TvService/Scheduler/Scheduler.cs
===================================================================
--- TvEngine3/TVLibrary/TvService/Scheduler/Scheduler.cs	(revision 27484)
+++ TvEngine3/TVLibrary/TvService/Scheduler/Scheduler.cs	(working copy)
@@ -81,6 +81,11 @@
     /// </summary>
     private int _maxRecordFreeCardsToTry;
 
+    /// <summary>
+    /// Lookup table for new 'series link' schedule - used to guarantee the scheduler will only spawn a linked program once
+    /// </summary>
+    private readonly Dictionary<int, int> _scheduleLastRecordingStarted = new Dictionary<int, int>();
+
     #endregion
    
     #region ctor
@@ -198,6 +203,7 @@
           card = new VirtualCard(user);
           return true;
         }
+
       }
       return false;
     }
@@ -675,6 +681,10 @@
         case ScheduleRecordingType.WeeklyEveryTimeOnThisChannel:
           isTimeToRecord = IsTimeToRecordWeeklyEveryTimeOnThisChannel(schedule, currentTime);
           break;
+
+        case ScheduleRecordingType.SeriesLink:
+          isTimeToRecord = IsTimeToRecordSeriesLink(schedule, currentTime);
+          break;
       }
       return isTimeToRecord;
     }
@@ -757,6 +767,84 @@
       return isTimeToRecord;
     }
 
+    /// <summary>
+    /// Gets if its time to record a series link recording, doesnt record directly, spawns a new record once schedule
+    /// </summary>
+    /// <param name="schedule"></param>
+    /// <returns></returns>
+    private bool IsTimeToRecordSeriesLink(Schedule schedule, DateTime currentTime)
+    {
+      Channel scheduleChannel = schedule.ReferencedChannel();
+
+      if (scheduleChannel == null)
+        return false;
+
+      if (schedule.SeriesId == 0)
+        return false;
+
+      TvDatabase.Program currentProgram = scheduleChannel.GetProgramAt(currentTime.AddMinutes(schedule.PreRecordInterval), schedule.SeriesId);
+
+      
+
+      if (currentProgram != null)
+      {
+
+        //  If this schedule has already spawned this program, skip
+        if (_scheduleLastRecordingStarted.ContainsKey(schedule.IdSchedule) && _scheduleLastRecordingStarted[schedule.IdSchedule] == currentProgram.IdProgram)
+        {
+          Log.Write("Scheduler: Record once for \"" + schedule.ProgramName + "\" has already been spawned, skipping");
+          return false;
+        }
+
+        if (currentTime >= currentProgram.StartTime.AddMinutes(-schedule.PreRecordInterval) &&
+            currentTime <= currentProgram.EndTime.AddMinutes(schedule.PostRecordInterval) &&
+            currentProgram.SeriesId > 0 &&
+            currentProgram.SeriesId == schedule.SeriesId)
+        {
+          if (!schedule.IsSerieIsCanceled(currentProgram.StartTime))
+          {
+            Log.Write("Scheduler: Time to record series link - " + schedule.ProgramName);
+
+            bool createSpawnedOnceSchedule = CreateSpawnedOnceSchedule(schedule, currentProgram);
+
+
+            if (createSpawnedOnceSchedule)
+            {
+              //  Add the last program spawned to the lookup to prevent this schedule spawning this program again
+              if (_scheduleLastRecordingStarted.ContainsKey(schedule.IdSchedule))
+              {
+                Log.Write("Scheduler: Updating last spawned program id to " + currentProgram.IdProgram.ToString() + " for schedule id " + schedule.IdSchedule.ToString());
+
+                _scheduleLastRecordingStarted[schedule.IdSchedule] = currentProgram.IdProgram;
+                Log.Write("Scheduler: Done last action");
+
+              }
+
+              else
+              {
+                Log.Write("Scheduler: Adding last spawned program id to " + currentProgram.IdProgram.ToString() + " for schedule id " + schedule.IdSchedule.ToString());
+
+                _scheduleLastRecordingStarted.Add(schedule.IdSchedule, currentProgram.IdProgram);
+              }
+
+              //  If this is the last episode in the series link, we want to delete the schedule
+              if (currentProgram.SeriesTermination == 1)
+              {
+                Log.Write("Scheduler: This is the last episode in the series.  Deleting series link schedule");
+                schedule.Delete();
+              }
+
+              Log.Write("Scheduler: Spawned record once schedule, resetting timer");
+              ResetTimer(); //lets process the spawned once schedule at once.
+            }
+          }
+        }
+      }
+
+      //  Series link schedule never records directly
+      return false;
+    }
+
     private RecordingDetail IsTimeToRecordWeekly(Schedule schedule, DateTime currentTime, out bool isTimeToRecord)
     {
       isTimeToRecord = false;
@@ -832,6 +920,8 @@
 
         if (once == null) // make sure that we DO NOT create multiple once recordings.
         {
+          Log.Write("Scheduler: Spawning record once - " + current.Description + ", start time: " + current.StartTime.ToString());
+
           Schedule newSchedule = new Schedule(schedule);
           newSchedule.IdChannel = current.IdChannel;
           newSchedule.StartTime = current.StartTime;
@@ -845,6 +935,9 @@
         }
       }
 
+      if (!isSpawnedOnceScheduleCreated)
+        Log.Write("Scheduler: Once recording already scheduled");
+
       return isSpawnedOnceScheduleCreated;
     }
 
Index: TvEngine3/TVLibrary/TvService/TvService.csproj
===================================================================
--- TvEngine3/TVLibrary/TvService/TvService.csproj	(revision 27484)
+++ TvEngine3/TVLibrary/TvService/TvService.csproj	(working copy)
@@ -10,7 +10,7 @@
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>9.0.30729</ProductVersion>
+    <ProductVersion>9.0.21022</ProductVersion>
     <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{3BE4F3AA-36EB-4956-B000-E29C74FC6AB0}</ProjectGuid>
     <OutputType>WinExe</OutputType>
@@ -142,6 +142,10 @@
     </EmbeddedResource>
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="..\..\..\Common-MP-TVE3\DirectShowLib\DirectShowLib.csproj">
+      <Project>{CE009BFA-5EF6-4153-B2A1-2FA79698A9AE}</Project>
+      <Name>DirectShowLib</Name>
+    </ProjectReference>
     <ProjectReference Include="..\Plugins\PluginBase\PluginBase.csproj">
       <Project>{5EE20DC0-B22B-4BDB-828B-8DC5723A1873}</Project>
       <Name>PluginBase</Name>
