"""
Copyright (c) 2006, Jari Sukanen
All rights reserved.

Redistribution and use in source and binary forms, with or 
without modification, are permitted provided that the following 
conditions are met:
	* Redistributions of source code must retain the above copyright 
	  notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright 
	  notice, this list of conditions and the following disclaimer in 
	  the documentation and/or other materials provided with the 
	  distribution.
    * Names of the contributors may not be used to endorse or promote 
	  products derived from this software without specific prior written 
	  permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
THE POSSIBILITY OF SUCH DAMAGE.
"""

import sisreader 
import zlib
import sys

class SISFileHeader :
	def __init__(self) :
		self.uid1 = 0
		self.uid2 = 0
		self.uid3 = 0
		self.uidChecksum = 0

class SISField :
	def __init__(self) :
		self.type = 0
		self.length = None
		self.subFields = []
		
	def readFieldLength(self, fileReader) :
		length = fileReader.readBytesAsUint(4)
		if length & 0x80000000 > 0 :
			length = length << 32
			length |= fileReader.readBytesAsUint(4)
		return length
		
	def findField(self, fieldType, startIndex = 0) :
		result = None
		index = startIndex
		
		for field in self.subFields[startIndex:] :
			if field.type == fieldType :
				result = field
				break
			++index
		return (result, index)
		
	def readableStr(self) :
		return ""
	
	def traverse(self, handler, depth = 0) :
		handler.handleField(self, depth)
		for field in self.subFields :
			field.traverse(handler, depth + 1)
		
class SISUnsupportedField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fileReader.readPlainBytes(self.length)

class SISStringField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		self.data = None
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		buf = fileReader.readPlainBytes(self.length)
		self.data = u""
		while len(buf) > 0 :
			temp = buf[:2]
			buf = buf[2:]
			self.data += unichr(ord(temp[0]) | ord(temp[1]) << 8)
		
	def readableStr(self) :
		return self.data
		
class SISArrayField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		type = fileReader.readBytesAsInt(4)
		l = self.length - 4
		while l > 0 :
			field = SISFieldTypes[type]()
			field.type = type
			field.initFromFile(fileReader)
			self.subFields.append(field)
			
			l -= field.length + 4 # field length + the length field
			padding = fileReader.skipPadding()
			l -= padding

class SISCompressedField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		self.algorithm = None
		self.uncompressedDataSize = None
		self.data = None
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		self.algorithm = fileReader.readBytesAsUint(4)
		self.uncompressedDataSize = fileReader.readBytesAsUint(8)
		data = fileReader.readPlainBytes(self.length - 4 - 8)
		if self.algorithm == 0 :
			self.data = data
		elif self.algorithm == 1 :
			self.data = zlib.decompress(data)
			
class SISVersionField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		self.version = (-1, -1, -1)
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		major = fileReader.readBytesAsInt(4)
		minor = fileReader.readBytesAsInt(4)
		build = fileReader.readBytesAsInt(4)
		self.version = (major, minor, build)
		
	def readableStr(self) :
		return str(self.version)
	
class SISVersionRangeField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		self.fromVersion = None
		self.toVersion = None
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		self.fromVersion = fieldParser.parseField(fileReader)
		if self.length - fieldParser.lastReadBytes > 0  :
			self.toVersion = fieldParser.parseField(fileReader)
	
class SISDateField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		self.year = None
		self.month = None
		self.day = None
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		self.year = fileReader.readBytesAsUint(2)
		self.month = fileReader.readBytesAsUint(1)
		self.day = fileReader.readBytesAsUint(1)
	
	def readableStr(self) :
		return str(self.year) + "." + str(self.month) + "." + str(self.day)
	
class SISTimeField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		self.hours = None
		self.minutes = None
		self.seconds = None
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		self.hours = fileReader.readBytesAsUint(1)
		self.minutes = fileReader.readBytesAsUint(1)
		self.seconds = fileReader.readBytesAsUint(1)
	
	def readableStr(self) :
		return str(self.hours) + ":" + str(self.minutes) + ":" + str(self.seconds)
	
class SISDateTimeField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		self.date = None
		self.time = None
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		self.date = fieldParser.parseField(fileReader)
		self.time = fieldParser.parseField(fileReader)
	
class SISUidField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		self.uid = None
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		self.uid = fileReader.readBytesAsUint(4)
		
	def readableStr(self) :
		return hex(self.uid)
	
class SISLanguageField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		self.language = None
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		self.language = fileReader.readBytesAsUint(4)
		
	def readableStr(self) :
		return str(self.language)
	
class SISContentsField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		field = fieldParser.parseField(fileReader)
		while field :
			if field.type == 3 : # compressed<conroller>
				bufferReader = sisreader.SISBufferReader(field.data)
				field = fieldParser.parseField(bufferReader)
			self.subFields.append(field)
			field = fieldParser.parseField(fileReader)

class SISControllerField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		bufferReader = sisreader.SISBufferReader(fileReader.readPlainBytes(self.length))
		field = fieldParser.parseField(bufferReader)
		while field :
			self.subFields.append(field)
			field = fieldParser.parseField(bufferReader)

class SISInfoField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		self.installType = None
		self.installFlags = None
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		self.subFields.append(fieldParser.parseField(fileReader)) # UID
		self.subFields.append(fieldParser.parseField(fileReader)) # Vendor name unique
		self.subFields.append(fieldParser.parseField(fileReader)) # names
		self.subFields.append(fieldParser.parseField(fileReader)) # vendor names
		self.subFields.append(fieldParser.parseField(fileReader)) # version
		self.subFields.append(fieldParser.parseField(fileReader)) # creation time
		self.installType = fileReader.readBytesAsUint(1)
		self.installFlags = fileReader.readBytesAsUint(1) 
			
class SISSupportedLanguagesField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		self.subFields.append(fieldParser.parseField(fileReader)) # languages
		
class SISSupportedOptionsField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		self.subFields.append(fieldParser.parseField(fileReader)) # options
			
class SISPrerequisitiesField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		self.subFields.append(fieldParser.parseField(fileReader)) # target devices
		self.subFields.append(fieldParser.parseField(fileReader)) # dependencies
		
import pdb
        
class SISDependencyField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		self.subFields.append(fieldParser.parseField(fileReader)) # UID
		field = fieldParser.parseField(fileReader)
		# Version range field is optional
		if field.type == VersionRangeField :
			self.subFields.append(field) # version range
			self.subFields.append(fieldParser.parseField(fileReader)) # dependency names
		else :
			self.subFields.append(field) # dependency names
	
class SISPropertiesField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		self.subFields.append(fieldParser.parseField(fileReader)) # properties
	
class SISPropertyField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		self.key = None
		self.value = None
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		self.key = fileReader.readBytesAsInt(4)
		self.value = fileReader.readBytesAsInt(4)
	
# There is a type for this field, but there is no definition of the field contents
class SISSignaturesField(SISUnsupportedField) :
	pass
	
class SISCertificateChainField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		self.subFields.append(fieldParser.parseField(fileReader)) # certificate data
	
class SISLogoField(SISField) :
	def __init__(self) :
		SISField.__init__(self)

	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		self.subFields.append(fieldParser.parseField(fileReader)) # logo file
	
class SISFileDescriptionField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		self.operation = None
		self.operationOptions = None
		self.compressedLength = None
		self.uncompressedLength = None
		self.fileIndex = None
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		
		self.subFields.append(fieldParser.parseField(fileReader))
		self.subFields.append(fieldParser.parseField(fileReader))
		field = fieldParser.parseField(fileReader)
		self.subFields.append(field)
		if field.type == 41 : # read field was capabilities ==> there is one more field left
			self.subFields.append(fieldParser.parseField(fileReader))
		
		self.operation = fileReader.readBytesAsUint(4)
		self.operationOptions = fileReader.readBytesAsUint(4)
		self.compressedLength = fileReader.readBytesAsUint(8)
		self.uncompressedLength = fileReader.readBytesAsUint(8)
		self.fileIndex = fileReader.readBytesAsUint(4)
		
	def readableStr(self) :
		return "index: " + str(self.fileIndex)
	
class SISHashField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		self.algorithm = None

	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		self.algorithm = fileReader.readBytesAsUint(4)
		self.subFields.append(fieldParser.parseField(fileReader)) # logo file
	
class SISIfField(SISField) :
	def __init__(self) :
		SISField.__init__(self)

	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		self.subFields.append(fieldParser.parseField(fileReader)) # expression
		self.subFields.append(fieldParser.parseField(fileReader)) # install block
		self.subFields.append(fieldParser.parseField(fileReader)) # else ifs

class SISElseIfField(SISField) :
	def __init__(self) :
		SISField.__init__(self)

	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		self.subFields.append(fieldParser.parseField(fileReader)) # expression
		self.subFields.append(fieldParser.parseField(fileReader)) # install block
	
class SISInstallBlockField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		self.files = None
		self.embeddedSISFiles = None
		self.ifBlocks = None
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		self.subFields.append(fieldParser.parseField(fileReader))
		self.subFields.append(fieldParser.parseField(fileReader))
		self.subFields.append(fieldParser.parseField(fileReader))

class SISExpressionField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		self.operator = None
		self.integerValue = None
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		self.operator = fileReader.readBytesAsUint(4)
		self.integerValue = fileReader.readBytesAsInt(4)
		
		if self.operator == 10 or self.operator == 13 :
			self.subFields.append(fieldParser.parseField(fileReader))
		if self.operator == 1 or self.operator == 2 or self.operator == 3 or self.operator == 4 or self.operator == 5 or self.operator == 6 or self.operator == 7 or self.operator == 8 or self.operator == 11 or self.operator == 12 :
			self.subFields.append(fieldParser.parseField(fileReader))
		if not (self.operator == 13 or self.operator == 14 or self.operator == 15 or self.operator == 16 or self.operator == 10) :
			self.subFields.append(fieldParser.parseField(fileReader))
		
class SISDataField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		self.subFields.append(fieldParser.parseField(fileReader)) # data units
	
class SISDataUnitField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		self.subFields.append(fieldParser.parseField(fileReader)) # file data
	
class SISFileDataField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		self.subFields.append(fieldParser.parseField(fileReader)) # raw file data
	
class SISSupportedOptionField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		self.subFields.append(fieldParser.parseField(fileReader)) # names
	
class SISControllerChecksumField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		self.checksum = None
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		self.checksum = fileReader.readBytesAsUint(2)
	
class SISDataChecksumField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		self.checksum = None
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		self.checksum = fileReader.readBytesAsUint(2)
	
class SISSignatureField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		self.subFields.append(fieldParser.parseField(fileReader)) # signature algorithm
		self.subFields.append(fieldParser.parseField(fileReader)) # signature data
	
class SISBlobField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		self.data = None
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		self.data = fileReader.readPlainBytes(self.length)
	
class SISSignatureAlgorithmField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		self.subFields.append(fieldParser.parseField(fileReader)) # algorithm identifier
	
class SISSignatureCertificateChainField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		fieldParser = sisreader.SISFieldParser()
		self.subFields.append(fieldParser.parseField(fileReader)) # signatures
		self.subFields.append(fieldParser.parseField(fileReader)) # certificate chain
	
class SISDataIndexField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		self.dataIndex = None
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		self.dataIndex = fileReader.readBytesAsUint(4)

class SISCapabilitiesField(SISField) :
	def __init__(self) :
		SISField.__init__(self)
		self.capabilities = 0
		self.readableCaps = []
		
	def initFromFile(self, fileReader) :
		self.length = self.readFieldLength(fileReader)
		self.capabilities = fileReader.readBytesAsUint(self.length)
		
		for i in range(20) :
			if (self.capabilities >> i) & 0x01 :
				self.readableCaps.append(CapabilityNames[i])
				
	def readableStr(self) :
		return " ".join(self.readableCaps)
	
SISFieldTypes = { 
	1 : SISStringField,
	2 : SISArrayField,
	3 : SISCompressedField,
	4 : SISVersionField,
	5 : SISVersionRangeField,
	6 : SISDateField,
	7 : SISTimeField,
	8 : SISDateTimeField,
	9 : SISUidField,
	10 : SISUnsupportedField,
	11 : SISLanguageField,
	12 : SISContentsField,
	13 : SISControllerField,
	14 : SISInfoField,
	15 : SISSupportedLanguagesField,
	16 : SISSupportedOptionsField,
	17 : SISPrerequisitiesField,
	18 : SISDependencyField,
	19 : SISPropertiesField,
	20 : SISPropertyField,
	21 : SISSignaturesField,
	22 : SISCertificateChainField,
	23 : SISLogoField,
	24 : SISFileDescriptionField,
	25 : SISHashField,
	26 : SISIfField,
	27 : SISElseIfField,
	28 : SISInstallBlockField,
	29 : SISExpressionField,
	30 : SISDataField,
	31 : SISDataUnitField,
	32 : SISFileDataField,
	33 : SISSupportedOptionField,
	34 : SISControllerChecksumField,
	35 : SISDataChecksumField,
	36 : SISSignatureField,
	37 : SISBlobField,
	38 : SISSignatureAlgorithmField,
	39 : SISSignatureCertificateChainField,
	40 : SISDataIndexField,
	41 : SISCapabilitiesField
	}

[StringField, 
 ArrayField, 
 CompressedField,
 VersionField,
 VersionRangeField,
 DateField,
 TimeField,
 DateTimeField,
 UidField,
 UnusedField,
 LanguageField,
 ContentsField,
 ControllerField,
 InfoField,
 SupportedLanguagesField,
 SupportedOptionsField,
 PrerequisitiesField,
 DependencyField,
 PropertiesField,
 PropertyField,
 SignaturesField,
 CertificateChainField,
 LogoField,
 FileDescriptionField,
 HashField,
 IfField,
 ElseIfField,
 InstallBlockField,
 ExpressionField,
 DataField,
 DataUnitField,
 FileDataField,
 SupportedOptionField,
 ControllerChecksumField,
 DataChecksumField,
 SignatureField,
 BlobField,
 SignatureAlgorithmField,
 SignatureCertificateChainField,
 DataIndexField,
 CapabilitiesField] = range(1, 42)
	 
FieldNames = {
 0 : "ROOT",
 StringField : "StringField", 
 ArrayField : "ArrayField", 
 CompressedField : "CompressedField",
 VersionField : "VersionField",
 VersionRangeField : "VersionRangeField",
 DateField : "DateField",
 TimeField : "TimeField",
 DateTimeField : "DateTimeField",
 UidField : "UidField",
 UnusedField : "UnusedField",
 LanguageField : "LanguageField",
 ContentsField : "ContentsField",
 ControllerField : "ControllerField",
 InfoField : "InfoField",
 SupportedLanguagesField : "SupportedLanguagesField",
 SupportedOptionsField : "SupportedOptionsField",
 PrerequisitiesField : "PrerequisitiesField",
 DependencyField : "DependencyField",
 PropertiesField : "PropertiesField",
 PropertyField : "PropertyField",
 SignaturesField : "SignaturesField",
 CertificateChainField : "CertificateChainField",
 LogoField : "LogoField",
 FileDescriptionField : "FileDescriptionField",
 HashField : "HashField",
 IfField : "IfField",
 ElseIfField : "ElseIfField",
 InstallBlockField : "InstallBlockField",
 ExpressionField : "ExpressionField",
 DataField : "DataField",
 DataUnitField : "DataUnitField",
 FileDataField : "FileDataField",
 SupportedOptionField : "SupportedOptionField",
 ControllerChecksumField : "ControllerChecksumField",
 DataChecksumField : "DataChecksumField",
 SignatureField : "SignatureField",
 BlobField : "BlobField",
 SignatureAlgorithmField : "SignatureAlgorithmField",
 SignatureCertificateChainField : "SignatureCertificateChainField",
 DataIndexField : "DataIndexField",
 CapabilitiesField : "CapabilitiesField"
}
	 
CapabilityNames = {
	0 : "TCB",
	1 : "CommDD",
	2 : "PowerMgmt",
	3 : "MultimediaDD",
	4 : "ReadDeviceData",
	5 : "WriteDeviceData",
	6 : "DRM",
	7 : "TrustedUI",
	8 : "ProtServ",
	9 : "DiskAdmin",
	10 : "NetworkControl",
	11 : "AllFiles",
	12 : "SwEvent",
	13 : "NetworkServices",
	14 : "LocalServices",
	15 : "ReadUserData",
    16 : "WriteUserData",
	17 : "Location",
	18 : "SurroundingsDD",
	19 : "UserEnvironment"
	}