'INFO: La costante di precompilatore SIEMENS =0 salta la logica che richiede le librerie Siemens. =1 compila tutto

#If SIEMENS Then

' declaring namespace for SINUMERIK Interface
Imports Siemens.Sinumerik.Operate.Services

Namespace CNC

  Partial Public Class SIEMENS
    Inherits CNC

    Private m_DataSvcRW As DataSvc
    Private m_DriveSVC As DrivesSvc
    Private m_AlarmService As AlarmSvc
    Private m_AlarmGuid As System.Guid
    Private currAlarms As Alarm()

    Private itemRead() As Item
    Private itemWrite As Item

    Public Overrides Property Licenza() As Integer
      Get
        Dim nLicence(0) As Integer
        'leggo dal cn il valore
        Me.S_RW_Integer(R, 255, 120, nLicence)
        Return nLicence(0)
      End Get
      Set(ByVal value As Integer)
        'setto sul cn il valore
        Dim nLicence(0) As Integer
        nLicence(0) = value
        Me.S_RW_Integer(W, 255, 120, nLicence)
      End Set
    End Property

    Public Overrides Property LicenzaScaduta() As Boolean
      Get
        Dim bLicenzaScaduta As Boolean
        'leggo dal cn il valore
        Me.S_RW_Boolean(R, 255, 92, 5, bLicenzaScaduta)
        Return bLicenzaScaduta
      End Get
      Set(ByVal value As Boolean)
        'setto sul cn il valore
        Me.S_RW_Boolean(W, 255, 92, 5, value)
      End Set
    End Property


    'Public Sub New(Optional ByRef szLang As String = "eng")
    Public Sub New()
      MyBase.New()
      _Type = NcType.SIEMENS

      ' commentato in blocco: c aspettiamo che il CmsControl, che lancia l'adapter, si occupi della verifica dell'HMI siemens
      ''verifico di aver prima avviato la Sinumerik HMI
      'If FindProcess("slsmhmihost") Is Nothing Then
      '    'MessageBox.Show("Sinumerik HMI process not found!" & vbNewLine & _
      '    '                "Run Sinumerik HMI before starting CMS Control.", My.Application.Info.Title, MessageBoxButtons.OK, MessageBoxIcon.Stop)
      '    Throw New CmsNcException("ERR Sinumerik HMI process not found CNC.SIEMENS")
      'End If

      Try
        m_DataSvcRW = New DataSvc
        m_DriveSVC = New DrivesSvc
        m_AlarmService = New AlarmSvc("eng")
        ' sottoscrivo allarmi...
        m_AlarmGuid = m_AlarmService.Subscribe(New AlarmListChanged(AddressOf AlarmList))

      Catch ex As System.IO.FileNotFoundException
        ' intercetta l'exception se non lanciato sopra l'hmi
        'MessageBox.Show("CMS Control must be run over Sinumerik Operate!" & vbNewLine & _
        '"Run CMS Control through shortcut.", My.Application.Info.Title, MessageBoxButtons.OK, MessageBoxIcon.Stop)
        Throw New CmsNcException("ERR CMS Control must be run over Sinumerik Operate CNC.SIEMENS")
      End Try

    End Sub

    Public Overrides Sub Connect(Optional ByRef szStatus As String = "")
      Try
        'se non ho eccezioni dichiaro connessione avvenuta
        _bConnected = True
        'Log.WI("OK  Connect CNC.SIEMENS", "Connected=" & _bConnected, CLog.Lev.Secondary)
      Catch ex As Exception
        Throw New CmsNcException("ERR Connect CNC.SIEMENS", ex)
      End Try

    End Sub

    Public Overrides Sub Disconnect(Optional ByRef szStatus As String = "")
      Try
        'dichiaro disconnessione avvenuta
        _bConnected = False
        'Log.WI("OK  Disconnect CNC.SIEMENS", "Connected=" & _bConnected, CLog.Lev.Secondary)
      Catch ex As Exception
        Throw New CmsNcException("ERR Disconnect CNC.SIEMENS", ex)
      End Try
    End Sub

    ''' <summary>
    ''' Legge le memorie di configurazione dal cn
    ''' </summary>
    Public Overrides Sub GetStaticData()

      If Not bStaticDataReaded Then

        Try
          ReDim itemRead(2)
          itemRead(0) = New Item("DB255.DBW0") 'Matricola
          itemRead(1) = New Item("DB255.DBW8") 'Teste
          itemRead(2) = New Item("DB255.DBW12") 'Magazzini
          m_DataSvcRW.Read(itemRead)
          Me._Matricola = itemRead(0).Value
          Me._Teste = itemRead(1).Value
          Me._Magazzini = itemRead(2).Value

          ReDim itemRead(0)
          itemRead(0) = New Item("DB254.DBB40:[20]") 'Manine per Magazzino
          m_DataSvcRW.Read(itemRead)
          ReDim Me._ManineMagazzino(Me._Magazzini - 1)
          For i = 0 To Me._Magazzini - 1
            Me._ManineMagazzino(i) = itemRead(0).Value(i)
          Next

          'Magazzini Con Attrezzaggio Automatico (maschera)
          ReDim itemRead(0)
          itemRead(0) = New Item("DB253.DBB19:[3]") 'Maschera Magazzini con attrezzaggio automatico
          m_DataSvcRW.Read(itemRead)
          Me._MagazziniConAttrezzaggioAutomatico = WordsToInteger(ByteToWord(itemRead(0).Value(0), itemRead(0).Value(1)), ByteToWord(itemRead(0).Value(2), 0))

          ReDim itemRead(0)
          itemRead(0) = New Item("/NC/_N_NC_TEA_ACX/$MN_MM_NUM_TOOL") 'Number of tools the NCK can manage
          m_DataSvcRW.Read(itemRead)
          Me._MaxUtensiliGestibili = itemRead(0).Value
          Me._MaxIdUtensile = 32000

          ReDim itemRead(0)
          itemRead(0) = New Item("DB254.DBB390") 'ZoomSpeed
          m_DataSvcRW.Read(itemRead)
          If itemRead(0).Value > 0 And itemRead(0).Value <= 100 Then
            Me._ZoomSpeed = itemRead(0).Value
          Else
            Me._ZoomSpeed = 1
          End If

          bStaticDataReaded = True

        Catch ex As InfrastructureException
          Throw New CmsNcException("ERR GetStaticData CNC.SIEMENS InfrastructureException", ex)
        Catch ex As DataSvcException
          Throw New CmsNcException("ERR GetStaticData CNC.SIEMENS DataSvcException", ex)
        End Try

      End If
    End Sub

    ''' <summary>
    ''' Legge la riga del programma attivo
    ''' </summary>
    ''' <param name="Path">Numero processo</param>
    ''' <param name="Line">Riga in esecuzione del programma attivo</param>
    ''' <returns>True se andata a buon fine</returns>
    Public Overridable Overloads Function S_GetActiveLineProgram(ByVal Path As Integer, ByRef Line As String) As Boolean
      Dim itemRead() As Item
      Do
        Try
          ReDim itemRead(0)
          If Path = 0 Then
            itemRead(0) = New Item("/Channel/ProgramInfo/actBlock[u1,1]") 'Blocco programma attivo
          Else
            itemRead(0) = New Item("/Channel/ProgramInfo/actBlock[u" & Path & ",1]")
          End If


          m_DataSvcRW.Read(itemRead)
          Line = itemRead(0).Value

          Exit Do
        Catch ex As DataSvcBusyException
          Debug.Print(ex.Message)
        End Try
      Loop

      Return True
    End Function

    ''' <summary>
    ''' Legge o scrive Boolean da MEMORIE PLC
    ''' </summary>
    ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
    ''' <param name="ItemPath">Stringa di indirizzamento Siemens</param>
    ''' <param name="Value">Valore da scrivere su scrittura e letto su lettura</param>
    ''' <returns>True se andata a buon fine</returns>
    Public Overloads Function S_RW_Boolean(ByVal bWrite As Boolean, ByVal ItemPath As String, ByRef Value As Boolean) As Boolean
      Dim itemRW As Item

      If bWrite Then ' *** Write
        Try
          itemRW = New Item(ItemPath)
          'set value
          itemRW.Value = Value
          Do
            Try
              m_DataSvcRW.Write(itemRW)
              Exit Do
            Catch ex As DataSvcBusyException
              Debug.Print(ex.Message)
            End Try
          Loop
        Catch ex As Exception
          'Log.WW("ERR m_DataSvcRW.Write on S_RW_Boolean CNC.SIEMENS", ex.Message, True)
          Return False
        End Try

      Else ' ************* Read
        Try
          itemRW = New Item(ItemPath)
          Do
            Try
              m_DataSvcRW.Read(itemRW)
              Exit Do
            Catch ex As DataSvcBusyException
              Debug.Print(ex.Message)
            End Try
          Loop
          Value = itemRW.Value
        Catch ex As Exception
          'Log.WW("ERR m_DataSvcRW.Read on S_RW_Boolean CNC.SIEMENS", ex.Message, True)
          Return False
        End Try
      End If

      Return True
    End Function



    ''' <summary>
    ''' Legge o scrive Boolean da MEMORIE PLC
    ''' </summary>
    ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
    ''' <param name="MemType">Tipo memoria</param>
    ''' <param name="MemoryIndex">Memoria del DB contenente il valore</param>
    ''' <param name="BitIndex">Bit della Memoria del DB contenente il valore</param>
    ''' <param name="Value">Valore da scrivere su scrittura e letto su lettura</param>
    ''' <returns>True se andata a buon fine</returns>
    Public Overloads Function S_RW_Boolean(ByVal bWrite As Boolean, ByVal MemType As Integer, ByVal MemoryIndex As Integer, ByVal BitIndex As Integer, ByRef Value As Boolean) As Boolean
      Dim itemRW As Item
      Dim ItemPath As String
      Dim cValue(0) As Byte

      ItemPath = "DB" & MemType.ToString & ".DBX" & MemoryIndex.ToString & "." & BitIndex.ToString

      If bWrite Then ' *** Write
        Try
          If MemType = MEM_S_M Then
            'leggo il byte
            S_RW_Byte(R, MEM_S_M, MemoryIndex, cValue)
            'set value
            cValue(0) = cValue(0) Or (2 ^ BitIndex)
            'riscrivo il byte
            S_RW_Byte(W, MEM_S_M, MemoryIndex, cValue)
          ElseIf MemType = MEM_S_E Then
            'leggo il byte
            S_RW_Byte(R, MEM_S_E, MemoryIndex, cValue)
            'set value
            cValue(0) = cValue(0) Or (2 ^ BitIndex)
            'riscrivo il byte
            S_RW_Byte(W, MEM_S_E, MemoryIndex, cValue)
          ElseIf MemType = MEM_S_A Then
            'leggo il byte
            S_RW_Byte(R, MEM_S_A, MemoryIndex, cValue)
            'set value
            cValue(0) = cValue(0) Or (2 ^ BitIndex)
            'riscrivo il byte
            S_RW_Byte(W, MEM_S_A, MemoryIndex, cValue)
          Else
            itemRW = New Item(ItemPath)
            'set value
            itemRW.Value = Value

            Do
              Try
                m_DataSvcRW.Write(itemRW)
                Exit Do
              Catch ex As DataSvcBusyException
                Debug.Print(ex.Message)
              End Try
            Loop
          End If

        Catch ex As DataSvcException
          'Log.WW("ERR m_DataSvcRW.Write on S_RW_Boolean CNC.SIEMENS DataSvcException", ex.Message & vbNewLine & ex.StackTrace)
        Catch ex As Exception
          'Log.WW("ERR m_DataSvcRW.Write on S_RW_Boolean CNC.SIEMENS", ex.Message, True)
          Return False
        End Try

      Else ' ************* Read
        Try
          itemRW = New Item(ItemPath)

          If MemType = MEM_S_M Then
            'leggo il byte
            S_RW_Byte(R, MEM_S_M, MemoryIndex, cValue)
            Value = ((cValue(0) And (2 ^ BitIndex)) = (2 ^ BitIndex))
          ElseIf MemType = MEM_S_E Then
            'leggo il byte
            S_RW_Byte(R, MEM_S_E, MemoryIndex, cValue)
            Value = ((cValue(0) And (2 ^ BitIndex)) = (2 ^ BitIndex))
          ElseIf MemType = MEM_S_A Then
            'leggo il byte
            S_RW_Byte(R, MEM_S_A, MemoryIndex, cValue)
            Value = ((cValue(0) And (2 ^ BitIndex)) = (2 ^ BitIndex))
          Else
            Do
              Try
                m_DataSvcRW.Read(itemRW)
                Exit Do
              Catch ex As DataSvcBusyException
                Debug.Print(ex.Message)
              End Try
            Loop
            Value = itemRW.Value
          End If

        Catch ex As DataSvcException
          'Log.WW("ERR m_DataSvcRW.Read on S_RW_Boolean CNC.SIEMENS DataSvcException", ex.Message & vbNewLine & ex.StackTrace)
        Catch ex As Exception
          'Log.WW("ERR m_DataSvcRW.Read on S_RW_Boolean CNC.SIEMENS", ex.Message, True)
          Return False
        End Try
      End If

      Return True
    End Function


    ''' <summary>
    ''' Legge o scrive Byte da MEMORIE PLC
    ''' </summary>
    ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
    ''' <param name="MemType">Tipo memoria</param>
    ''' <param name="MemoryIndex">Memoria del DB contenente il valore</param>
    ''' <param name="Value">Valore da scrivere su scrittura e letto su lettura</param>
    ''' <returns>True se andata a buon fine</returns>
    Public Overloads Function S_RW_Byte(ByVal bWrite As Boolean, ByVal MemType As Integer, ByVal MemoryIndex As Integer, ByRef Value() As Byte) As Boolean
      Dim itemRW As Item
      Dim ItemPath As String

      If MemType = MEM_S_M Then
        ItemPath = "MB" & MemoryIndex.ToString
      ElseIf MemType = MEM_S_E Then
        ItemPath = "EB" & MemoryIndex.ToString
      ElseIf MemType = MEM_S_A Then
        ItemPath = "AB" & MemoryIndex.ToString
      Else
        ItemPath = "DB" & MemType.ToString & ".DBB" & MemoryIndex.ToString
      End If
      If Value.Length > 1 Then ItemPath &= ":[" & Value.Length.ToString & "]"

      If bWrite Then ' *** Write
        Try
          itemRW = New Item(ItemPath)
          'set value
          If Value.Length = 1 Then
            itemRW.Value = Value(0)
          Else
            ReDim itemRW.Value(Value.Length - 1)
            For i As Integer = 0 To Value.Length - 1
              itemRW.Value(i) = Value(i)
            Next i
          End If
          Do
            Try
              m_DataSvcRW.Write(itemRW)
              Exit Do
            Catch ex As DataSvcBusyException
              Debug.Print(ex.Message)
            End Try
          Loop
        Catch ex As DataSvcException
          'Log.WW("ERR m_DataSvcRW.Write on S_RW_Byte CNC.SIEMENS DataSvcException", ex.Message & vbNewLine & ex.StackTrace)
        Catch ex As Exception
          'Log.WW("ERR m_DataSvcRW.Write on S_RW_Byte CNC.SIEMENS", ex.Message, True)
          Return False
        End Try

      Else ' ************* Read
        Try
          itemRW = New Item(ItemPath)
          Do
            Try
              m_DataSvcRW.Read(itemRW)
              Exit Do
            Catch ex As DataSvcBusyException
              Debug.Print(ex.Message)
            End Try
          Loop

          If Value.Length = 1 Then
            Value(0) = itemRW.Value
          Else
            For i As Integer = 0 To Value.Length - 1
              Value(i) = itemRW.Value(i)
            Next i
          End If
        Catch ex As DataSvcException
          'Log.WW("ERR m_DataSvcRW.Read on S_RW_Byte CNC.SIEMENS DataSvcException", ex.Message & vbNewLine & ex.StackTrace)
        Catch ex As Exception
          'Log.WW("ERR m_DataSvcRW.Read on S_RW_Byte CNC.SIEMENS", ex.Message)
          Return False
        End Try
      End If

      Return True
    End Function

    ''' <summary>
    ''' Legge o scrive Word da MEMORIE PLC
    ''' </summary>
    ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
    ''' <param name="MemType">Tipo memoria</param>
    ''' <param name="MemoryIndex">Memoria del DB contenente il valore</param>
    ''' <param name="Value">Valore da scrivere su scrittura e letto su lettura</param>
    ''' <returns>True se andata a buon fine</returns>
    Public Overloads Function S_RW_Word(ByVal bWrite As Boolean, ByVal MemType As Integer, ByVal MemoryIndex As Integer, ByRef Value() As UShort) As Boolean
      Dim itemRW As Item
      Dim ItemPath As String

      If MemType = MEM_S_M Then
        ItemPath = "MW" & MemoryIndex.ToString
      ElseIf MemType = MEM_S_E Then
        ItemPath = "EW" & MemoryIndex.ToString
      ElseIf MemType = MEM_S_A Then
        ItemPath = "AW" & MemoryIndex.ToString
      Else
        ItemPath = "DB" & MemType.ToString & ".DBW" & MemoryIndex.ToString
      End If
      If Value.Length > 1 Then ItemPath &= ":[" & Value.Length.ToString & "]"

      If bWrite Then ' *** Write
        Try
          itemRW = New Item(ItemPath)
          'set value
          If Value.Length = 1 Then
            itemRW.Value = Value(0)
          Else
            ReDim itemRW.Value(Value.Length - 1)
            For i As Integer = 0 To Value.Length - 1
              itemRW.Value(i) = Value(i)
            Next i
          End If
          Do
            Try
              m_DataSvcRW.Write(itemRW)
              Exit Do
            Catch ex As DataSvcBusyException
              Debug.Print(ex.Message)
            End Try
          Loop

        Catch ex As DataSvcException
          'Log.WW("ERR m_DataSvcRW.Write on S_RW_Word CNC.SIEMENS DataSvcException", ex.Message & vbNewLine & ex.StackTrace)
        Catch ex As Exception
          'Log.WW("ERR m_DataSvcRW.Write on S_RW_Word CNC.SIEMENS", ex.Message)
          Return False
        End Try

      Else ' ************* Read
        Try
          itemRW = New Item(ItemPath)
          Do
            Try
              m_DataSvcRW.Read(itemRW)
              Exit Do
            Catch ex As DataSvcBusyException
              Debug.Print(ex.Message)
            End Try
          Loop

          If Value.Length = 1 Then
            Value(0) = itemRW.Value
          Else
            For i As Integer = 0 To Value.Length - 1
              Value(i) = itemRW.Value(i)
            Next i
          End If

        Catch ex As DataSvcException
          'Log.WW("ERR m_DataSvcRW.Read on S_RW_Word CNC.SIEMENS DataSvcException", ex.Message & vbNewLine & ex.StackTrace)
        Catch ex As Exception
          'Log.WW("ERR m_DataSvcRW.Read on S_RW_Word CNC.SIEMENS", ex.Message, True)
          Return False
        End Try
      End If

      Return True
    End Function

    ''' <summary>
    ''' Legge o scrive Short da MEMORIE PLC
    ''' </summary>
    ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
    ''' <param name="MemType">Tipo memoria</param>
    ''' <param name="MemoryIndex">Memoria del DB contenente il valore</param>
    ''' <param name="Value">Valore da scrivere su scrittura e letto su lettura</param>
    ''' <returns>True se andata a buon fine</returns>
    Public Overloads Function S_RW_Short(ByVal bWrite As Boolean, ByVal MemType As Integer, ByVal MemoryIndex As Integer, ByRef Value() As Short) As Boolean
      Dim itemRW As Item
      Dim ItemPath As String

      If MemType = MEM_S_M Then
        ItemPath = "MW" & MemoryIndex.ToString
      ElseIf MemType = MEM_S_E Then
        ItemPath = "EW" & MemoryIndex.ToString
      ElseIf MemType = MEM_S_A Then
        ItemPath = "AW" & MemoryIndex.ToString
      Else
        ItemPath = "DB" & MemType.ToString & ".DBW" & MemoryIndex.ToString
      End If
      If Value.Length > 1 Then ItemPath &= ":[" & Value.Length.ToString & "]"

      If bWrite Then ' *** Write
        Try
          itemRW = New Item(ItemPath)
          'set value
          If Value.Length = 1 Then
            itemRW.Value = ShortToUnsigned(Value(0))
          Else
            ReDim itemRW.Value(Value.Length - 1)
            For i As Integer = 0 To Value.Length - 1
              itemRW.Value(i) = ShortToUnsigned(Value(i))
            Next i
          End If
          Do
            Try
              m_DataSvcRW.Write(itemRW)
              Exit Do
            Catch ex As DataSvcBusyException
              Debug.Print(ex.Message)
            End Try
          Loop

        Catch ex As DataSvcException
          'Log.WW("ERR m_DataSvcRW.Write on S_RW_Word CNC.SIEMENS DataSvcException", ex.Message & vbNewLine & ex.StackTrace)
        Catch ex As Exception
          'Log.WW("ERR m_DataSvcRW.Write on S_RW_Word CNC.SIEMENS", ex.Message)
          Return False
        End Try

      Else ' ************* Read
        Try
          itemRW = New Item(ItemPath)
          Do
            Try
              m_DataSvcRW.Read(itemRW)
              Exit Do
            Catch ex As DataSvcBusyException
              Debug.Print(ex.Message)
            End Try
          Loop

          If Value.Length = 1 Then
            Value(0) = itemRW.Value
          Else
            For i As Integer = 0 To Value.Length - 1
              Value(i) = UnsignedToShort(itemRW.Value(i))
            Next i
          End If

        Catch ex As DataSvcException
          'Log.WW("ERR m_DataSvcRW.Read on S_RW_Short CNC.SIEMENS DataSvcException", ex.Message & vbNewLine & ex.StackTrace)
        Catch ex As Exception
          'Log.WW("ERR m_DataSvcRW.Read on S_RW_Short CNC.SIEMENS", ex.Message, True)
          Return False
        End Try
      End If

      Return True
    End Function




    ''' <summary>
    ''' Legge o scrive DWord da MEMORIE PLC
    ''' </summary>
    ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
    ''' <param name="MemType">Tipo memoria</param>
    ''' <param name="MemoryIndex">Memoria del DB contenente il valore</param>
    ''' <param name="Value">Valore da scrivere su scrittura e letto su lettura</param>
    ''' <returns>True se andata a buon fine</returns>
    Public Overloads Function S_RW_DWord(ByVal bWrite As Boolean, ByVal MemType As Integer, ByVal MemoryIndex As Integer, ByRef Value() As UInteger) As Boolean
      Dim itemRW As Item
      Dim ItemPath As String

      If MemType = MEM_S_M Then
        ItemPath = "MD" & MemoryIndex.ToString
      ElseIf MemType = MEM_S_E Then
        ItemPath = "ED" & MemoryIndex.ToString
      ElseIf MemType = MEM_S_A Then
        ItemPath = "AD" & MemoryIndex.ToString
      Else
        ItemPath = "DB" & MemType.ToString & ".DBD" & MemoryIndex.ToString
      End If
      If Value.Length > 1 Then ItemPath &= ":[" & Value.Length.ToString & "]"

      If bWrite Then ' *** Write
        Try
          itemRW = New Item(ItemPath)
          'set value
          If Value.Length = 1 Then
            itemRW.Value = Value(0)
          Else
            ReDim itemRW.Value(Value.Length - 1)
            For i As Integer = 0 To Value.Length - 1
              itemRW.Value(i) = Value(i)
            Next i
          End If
          Do
            Try
              m_DataSvcRW.Write(itemRW)
              Exit Do
            Catch ex As DataSvcBusyException
              Debug.Print(ex.Message)
            End Try
          Loop

        Catch ex As DataSvcException
          'Log.WW("ERR m_DataSvcRW.Write on S_RW_DWord CNC.SIEMENS DataSvcException", ex.Message & vbNewLine & ex.StackTrace)
        Catch ex As Exception
          'Log.WW("ERR m_DataSvcRW.Write on S_RW_DWord CNC.SIEMENS", ex.Message)
          Return False
        End Try

      Else ' ************* Read
        Try
          itemRW = New Item(ItemPath)
          Do
            Try
              m_DataSvcRW.Read(itemRW)
              Exit Do
            Catch ex As DataSvcBusyException
              Debug.Print(ex.Message)
            End Try
          Loop

          If Value.Length = 1 Then
            Value(0) = itemRW.Value
          Else
            For i As Integer = 0 To Value.Length - 1
              Value(i) = itemRW.Value(i)
            Next i
          End If

        Catch ex As DataSvcException
          'Log.WW("ERR m_DataSvcRW.Read on S_RW_DWord CNC.SIEMENS DataSvcException", ex.Message & vbNewLine & ex.StackTrace)
        Catch ex As Exception
          'Log.WW("ERR m_DataSvcRW.Read on S_RW_DWord CNC.SIEMENS", ex.Message, True)
          Return False
        End Try
      End If

      Return True
    End Function
    ''' <summary>
    ''' Legge o scrive Integer da MEMORIE PLC
    ''' </summary>
    ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
    ''' <param name="MemType">Tipo memoria</param>
    ''' <param name="MemoryIndex">Memoria del DB contenente il valore</param>
    ''' <param name="Value">Valore da scrivere su scrittura e letto su lettura</param>
    ''' <returns>True se andata a buon fine</returns>
    Public Overloads Function S_RW_Integer(ByVal bWrite As Boolean, ByVal MemType As Integer, ByVal MemoryIndex As Integer, ByRef Value() As Integer) As Boolean
      Dim itemRW As Item
      Dim ItemPath As String

      If MemType = MEM_S_M Then
        ItemPath = "MD" & MemoryIndex.ToString
      ElseIf MemType = MEM_S_E Then
        ItemPath = "ED" & MemoryIndex.ToString
      ElseIf MemType = MEM_S_A Then
        ItemPath = "AD" & MemoryIndex.ToString
      Else
        ItemPath = "DB" & MemType.ToString & ".DBD" & MemoryIndex.ToString
      End If
      If Value.Length > 1 Then ItemPath &= ":[" & Value.Length.ToString & "]"

      If bWrite Then ' *** Write
        Try
          itemRW = New Item(ItemPath)
          'set value
          If Value.Length = 1 Then
            itemRW.Value = IntegerToUnsigned(Value(0))
          Else
            ReDim itemRW.Value(Value.Length - 1)
            For i As Integer = 0 To Value.Length - 1
              itemRW.Value(i) = IntegerToUnsigned(Value(i))
            Next i
          End If
          Do
            Try
              m_DataSvcRW.Write(itemRW)
              Exit Do
            Catch ex As DataSvcBusyException
              Debug.Print(ex.Message)
            End Try
          Loop

        Catch ex As DataSvcException
          'Log.WW("ERR m_DataSvcRW.Write on S_RW_Integer CNC.SIEMENS DataSvcException", ex.Message & vbNewLine & ex.StackTrace)
        Catch ex As Exception
          'Log.WW("ERR m_DataSvcRW.Write on S_RW_Integer CNC.SIEMENS", ex.Message)
          Return False
        End Try

      Else ' ************* Read
        Try
          itemRW = New Item(ItemPath)
          Do
            Try
              m_DataSvcRW.Read(itemRW)
              Exit Do
            Catch ex As DataSvcBusyException
              Debug.Print(ex.Message)
            End Try
          Loop

          If Value.Length = 1 Then
            Value(0) = UnsignedToInteger(itemRW.Value)
          Else
            For i As Integer = 0 To Value.Length - 1
              Value(i) = UnsignedToInteger(itemRW.Value(i))
            Next i
          End If

        Catch ex As DataSvcException
          'Log.WW("ERR m_DataSvcRW.Read on S_RW_Integer CNC.SIEMENS DataSvcException", ex.Message & vbNewLine & ex.StackTrace)
        Catch ex As Exception
          'Log.WW("ERR m_DataSvcRW.Read on S_RW_Integer CNC.SIEMENS", ex.Message, True)
          Return False
        End Try
      End If

      Return True
    End Function


    ''' <summary>
    ''' Legge o scrive Real da MEMORIE PLC
    ''' </summary>
    ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
    ''' <param name="MemType">Tipo memoria</param>
    ''' <param name="MemoryIndex">Memoria del DB contenente il valore</param>
    ''' <param name="Value">Valore da scrivere su scrittura e letto su lettura</param>
    ''' <returns>True se andata a buon fine</returns>
    Public Overloads Function S_RW_Real(ByVal bWrite As Boolean, ByVal MemType As Integer, ByVal MemoryIndex As Integer, ByRef Value() As Single) As Boolean
      Dim itemRW As Item
      Dim ItemPath As String

      If MemType = MEM_S_M Then
        ItemPath = "MD" & MemoryIndex.ToString
      ElseIf MemType = MEM_S_E Then
        ItemPath = "ED" & MemoryIndex.ToString
      ElseIf MemType = MEM_S_A Then
        ItemPath = "AD" & MemoryIndex.ToString
      Else
        ItemPath = "DB" & MemType.ToString & ".DBD" & MemoryIndex.ToString
      End If
      If Value.Length > 1 Then ItemPath &= ":[" & Value.Length.ToString & "]"

      If bWrite Then ' *** Write
        Try
          itemRW = New Item(ItemPath)
          'set value
          If Value.Length = 1 Then
            itemRW.Value = SingleToUInteger(Value(0))
          Else
            ReDim itemRW.Value(Value.Length - 1)
            For i As Integer = 0 To Value.Length - 1
              itemRW.Value(i) = SingleToUInteger(Value(i))
            Next i
          End If
          Do
            Try
              m_DataSvcRW.Write(itemRW)
              Exit Do
            Catch ex As DataSvcBusyException
              Debug.Print(ex.Message)
            End Try
          Loop

        Catch ex As DataSvcException
          'Log.WW("ERR m_DataSvcRW.Write on S_RW_Real CNC.SIEMENS DataSvcException", ex.Message & vbNewLine & ex.StackTrace)
        Catch ex As Exception
          'Log.WW("ERR m_DataSvcRW.Write on S_RW_Real CNC.SIEMENS", ex.Message)
          Return False
        End Try

      Else ' ************* Read
        Try
          itemRW = New Item(ItemPath)
          Do
            Try
              m_DataSvcRW.Read(itemRW)
              Exit Do
            Catch ex As DataSvcBusyException
              Debug.Print(ex.Message)
            End Try
          Loop

          If Value.Length = 1 Then
            Value(0) = UIntegerToSingle(itemRW.Value)
          Else
            For i As Integer = 0 To Value.Length - 1
              Value(i) = UIntegerToSingle(itemRW.Value(i))
            Next i
          End If

        Catch ex As DataSvcException
          'Log.WW("ERR m_DataSvcRW.Read on S_RW_Real CNC.SIEMENS DataSvcException", ex.Message & vbNewLine & ex.StackTrace)
        Catch ex As Exception
          'Log.WW("ERR m_DataSvcRW.Read on S_RW_Real CNC.SIEMENS", ex.Message, True)
          Return False
        End Try
      End If

      Return True
    End Function



    ''' <summary>
    ''' Legge o scrive LReal dalle MEMORIE R
    ''' </summary>
    ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
    ''' <param name="MemoryIndex">Memoria del DB contenente il valore</param>
    ''' <param name="Value">Valore da scrivere su scrittura e letto su lettura</param>
    ''' <returns>True se andata a buon fine</returns>
    Public Overloads Function S_RW_R_LReal(ByVal bWrite As Boolean, ByVal MemoryIndex As Integer, ByRef Value As Double, Optional ByVal nPath As Integer = 1) As Boolean
      Dim itemRW As Item
      Dim ItemPath As String

      ItemPath = "/channel/parameter/r[u" & nPath.ToString & "," & MemoryIndex.ToString & "]"

      If bWrite Then ' *** Write
        Try
          itemRW = New Item(ItemPath)
          'set value
          itemRW.Value = Value
          Do
            Try
              m_DataSvcRW.Write(itemRW)
              Exit Do
            Catch ex As DataSvcBusyException
              Debug.Print(ex.Message)
            End Try
          Loop

        Catch ex As DataSvcException
          'Log.WW("ERR m_DataSvcRW.Write on S_RW_R_LReal CNC.SIEMENS DataSvcException", ex.Message & vbNewLine & ex.StackTrace)
        Catch ex As Exception
          'Log.WW("ERR m_DataSvcRW.Write on S_RW_R_LReal CNC.SIEMENS", ex.Message)
          Return False
        End Try

      Else ' ************* Read
        Try
          itemRW = New Item(ItemPath)
          Do
            Try
              m_DataSvcRW.Read(itemRW)
              Exit Do
            Catch ex As DataSvcBusyException
              Debug.Print(ex.Message)
            End Try
          Loop

          Value = itemRW.Value

        Catch ex As DataSvcException
          'Log.WW("ERR m_DataSvcRW.Read on S_RW_R_LReal CNC.SIEMENS DataSvcException", ex.Message & vbNewLine & ex.StackTrace)
        Catch ex As Exception
          'Log.WW("ERR m_DataSvcRW.Read on S_RW_R_LReal CNC.SIEMENS", ex.Message, True)
          Return False
        End Try
      End If

      Return True
    End Function



#Region "Funzioni specifiche IOT"



    ''' <summary>
    ''' Struttura dati Posizione XYZ IJK
    ''' </summary>
    Public Structure PosizLav
      ''' <summary>
      ''' Valore X
      ''' </summary>
      Public X As Single
      ''' <summary>
      ''' Valore Y
      ''' </summary>
      Public Y As Single
      ''' <summary>
      ''' Valore Z
      ''' </summary>
      Public Z As Single
      ''' <summary>
      ''' Valore I
      ''' </summary>
      Public I As Single
      ''' <summary>
      ''' Valore J
      ''' </summary>
      Public J As Single
      ''' <summary>
      ''' Valore K
      ''' </summary>
      Public K As Single

    End Structure

    ''' <summary>
    ''' Struttura dati FeedSpeed
    ''' </summary>
    Public Structure FeedSpeedData
      ''' <summary>
      ''' Valore Feed
      ''' </summary>
      Public Feed As Single
      ''' <summary>
      ''' Valore Speed
      ''' </summary>
      Public Speed As Single

    End Structure


    ''' <summary>
    ''' Struttura dati MANDRINO
    ''' </summary>
    Public Structure UnOpData
      ''' <summary>
      ''' Carico Asse
      ''' </summary>
      Public Load As Single
      ''' <summary>
      ''' Speed asse
      ''' </summary>
      Public Speed As Single
    End Structure

    ''' <summary>
    ''' Struttura dati asse
    ''' </summary>
    Public Structure AxData
      ''' <summary>
      ''' Carico Asse
      ''' </summary>
      Public Load As Single
      ''' <summary>
      ''' posizione attuale asse
      ''' </summary>
      Public PosAct As Single
      ''' <summary>
      ''' posizione Target asse
      ''' </summary>
      Public PosTgt As Single
      ''' <summary>
      ''' Feed asse
      ''' </summary>
      Public Feed As Single
      ''' <summary>
      ''' Feed Override asse
      ''' </summary>
      Public FeedOver As Single
    End Structure
    ''' <summary>
    ''' Struttura dati UT
    ''' </summary>
    Public Structure UtData
      ''' <summary>
      ''' Vettore elenco UT (DB254.DBW280)
      ''' </summary>
      Public elencoUtMem As UShort()
      ''' <summary>
      ''' Tabella UT (DB253.DBW2500)
      ''' </summary>
      Public tabUt_UT As UShort()
      ''' <summary>
      ''' Tabella IdFamigliaUt (DB253.DBW2900)
      ''' </summary>
      Public tabIdFamUt As UShort()
      ''' <summary>
      ''' Tabella Famiglie Utensili (DB253.DBW100)
      ''' </summary>
      Public tabFamUt As UShort()
      ''' <summary>
      ''' Tabella TIPO Vita Residua Famiglie Utensili (DB253.DBB1900)
      ''' </summary>
      Public tabTipoVitaRes As Byte()
      ''' <summary>
      ''' Tabella Vita Residua Famiglie Utensili (DB253.DBD4300)
      ''' </summary>
      Public tabVitaRes As UInt32()

    End Structure


    ''' <summary>
    ''' Restituisce tutti i dati UnOp
    ''' </summary>
    ''' <returns></returns>
    Public Function getAllUnOpData() As UnOpData()
      ' RIFERIMENTO: 
      ' PLC interface

      ReDim itemRead(1)
      itemRead(0) = New Item("DB254.DBB180:[20]") 'Carico effettivo MANDRINO
      itemRead(1) = New Item("DB254.DBW140:[20]") 'Speed effettiva MANDRINO

      Do
        Try
          m_DataSvcRW.Read(itemRead)
          Exit Do
        Catch ex As DataSvcBusyException
          Debug.Print(ex.Message)
        Catch ex As DataSvcException
          Throw New CmsNcException("ERR GetStaticData CNC.SIEMENS DataSvcException", ex)
        End Try
      Loop

      Dim datiAssi(19) As UnOpData


      ' faccio copia valori!
      For i As Integer = 0 To 19
        datiAssi(i).Load = UIntegerToSingle(itemRead(0).Value(i))
        datiAssi(i).Speed = UIntegerToSingle(itemRead(1).Value(i))
      Next i

      Return datiAssi

    End Function

    ''' <summary>
    ''' Restituisce tutti i dati assi insieme
    ''' </summary>
    ''' <returns></returns>
    Public Function getAllAxisData() As AxData()
      ' RIFERIMENTO: 
      ' txt Giuseppe

      ReDim itemRead(4)
      itemRead(0) = New Item("DB241.DBD0:[16]")   'Posizione attuale
      itemRead(1) = New Item("/Channel/MachineAxis/actFeedRate[u1,1,16]") ' param manual NC, pg21 legge la feed... da salvare in valore assolulto...
      itemRead(2) = New Item("/Channel/MachineAxis/feedRateOvr[u1,1,16]") ' param manual NC, pg215 legge la feedOver... 
      itemRead(3) = New Item("/Channel/MachineAxis/toolBaseDistToGo[u1,1,16]")
      itemRead(4) = New Item("/Channel/MachineAxis/aaLoad[u1,1,16]") ' param manual NC, pg426 legge carico effettivo asse PRIFIdrive in %... da sempre zero 

      '/Channel/MachineAxis/speedOvr[u1,1,16] speed override asse NON VA - errore-eccezione
      '/Channel/NckSpindle/driveLoad[u1,1,16] carico effettivo asse NON VA - errore-eccezione
      '/Channel/MachineAxis/aaLoad[u1,1,16] pg426 carico effettivo asse DA SEMPRE ZERO 
      '/Channel/MachineAxis/vaLoad[u1,1,16] DA SEMPRE ZERO 
      '/Channel/MachineAxis/vaCurr[u1,1,16] DA SEMPRE ZERO 
      '

      Do
        Try
          m_DataSvcRW.Read(itemRead)
          Exit Do
        Catch ex As DataSvcBusyException
          Debug.Print(ex.Message)
        Catch ex As DataSvcException
          Throw New CmsNcException("ERR GetStaticData CNC.SIEMENS DataSvcException", ex)
        End Try
      Loop

      Dim datiAssi(15) As AxData

      ' faccio copia valori!
      For i As Integer = 0 To 15
        'datiAssi(i).PosAct = itemRead(0).Value(i)
        datiAssi(i).PosAct = UIntegerToSingle(itemRead(0).Value(i))
        datiAssi(i).Feed = Math.Abs(Convert.ToSingle(itemRead(1).Value(i)))
        datiAssi(i).FeedOver = Math.Abs(Convert.ToSingle(itemRead(2).Value(i)))
        datiAssi(i).PosTgt = Convert.ToSingle(itemRead(3).Value(i))
        datiAssi(i).Load = UIntegerToSingle(itemRead(4).Value(i))
      Next i

      Return datiAssi

    End Function

    ''' <summary>
    ''' recupera (e formatta) tutti i dati riferiti alle tabelle della gestione UT
    ''' </summary>
    ''' <param name="numVal"></param>
    ''' <returns></returns>
    Public Function getAllUtData(ByVal numVal As Short, ByVal numUt As Short) As UtData
      ' RIFERIMENTO: 
      ' txt Giuseppe

      ReDim itemRead(5)
      itemRead(0) = New Item("DB254.DBW280:[" & numUt & "]")      'elencoUtMem
      itemRead(1) = New Item("DB253.DBW2500:[" & numVal & "]")    'tabUt_UT
      itemRead(2) = New Item("DB253.DBW2900:[" & numVal & "]")    'IdFamigliaUt
      itemRead(3) = New Item("DB253.DBW100:[" & numVal & "]")     'tabFamUt
      itemRead(4) = New Item("DB253.DBB1900:[" & numVal & "]")    'tabTipoVitaRes
      itemRead(5) = New Item("DB253.DBD4300:[" & numVal & "]")    'tabVitaRes

      Do
        Try
          m_DataSvcRW.Read(itemRead)
          Exit Do
        Catch ex As DataSvcBusyException
          Debug.Print(ex.Message)
        Catch ex As DataSvcException
          Throw New CmsNcException("ERR GetStaticData CNC.SIEMENS DataSvcException", ex)
        End Try
      Loop

      ' variabili di appoggio
      Dim datiUT As New UtData

      Dim _elencoUtMem(numUt - 1) As UShort
      Dim _tabUt_UT(numVal - 1) As UShort
      Dim _tabIdFamUt(numVal - 1) As UShort
      Dim _tabFamUt(numVal - 1) As UShort
      Dim _tabTipoVitaRes(numVal - 1) As Byte
      Dim _tabVitaRes(numVal - 1) As UInt32

      ' faccio copia valori!
      For i As Integer = 0 To numUt - 1
        _elencoUtMem(i) = itemRead(0).Value(i)
        '_elencoUtMem(i) = UIntegerToSingle(itemRead(0).Value(i))
      Next i

      ' faccio copia valori!
      For i As Integer = 0 To numVal - 1

        _tabUt_UT(i) = itemRead(1).Value(i)
        '_tabUt_UT(i) = UIntegerToSingle(itemRead(1).Value(i))

        _tabIdFamUt(i) = itemRead(2).Value(i)
        '_tabIdFamUt(i) = UIntegerToSingle(itemRead(2).Value(i))

        _tabFamUt(i) = itemRead(3).Value(i)
        '_tabFamUt(i) = UIntegerToSingle(itemRead(3).Value(i))

        _tabTipoVitaRes(i) = itemRead(4).Value(i)
        '_tabTipoVitaRes(i) = UIntegerToSingle(itemRead(4).Value(i))

        _tabVitaRes(i) = itemRead(5).Value(i)
        '_tabVitaRes(i) = UIntegerToSingle(itemRead(5).Value(i))
      Next i

      ' copio in oggetto OUT...
      datiUT.elencoUtMem = _elencoUtMem
      datiUT.tabUt_UT = _tabUt_UT
      datiUT.tabFamUt = _tabFamUt
      datiUT.tabIdFamUt = _tabIdFamUt
      datiUT.tabTipoVitaRes = _tabTipoVitaRes
      datiUT.tabVitaRes = _tabVitaRes

      ' rendo i dati!
      Return datiUT

    End Function

    ''' <summary>
    ''' recupera l'array dei codici G attivi
    ''' </summary>
    ''' <param name="maxProc"></param>
    ''' <param name="GCodeCurr">Vettore codici attivi correnti</param>
    ''' <returns></returns>
    Public Function getPathGCodeMod(maxProc As Integer, ByRef GCodeCurr As String(,)) As Boolean
      ' RIFERIMENTO: 
      ' SynumerikOperate_net, pg 52
      ' Parameter manual NC, pg 401

      ' preparo memorie
      Dim maxGruppi As Int16
      maxGruppi = 64
      ReDim itemRead(maxProc - 1)
      For i As Integer = 0 To maxProc - 1
        itemRead(i) = New Item("/Channel/SelectedFunctions/ncFktAct[u" & i + 1 & ",1,#" & maxGruppi & "]")  ' leggo TUTTI i gruppi...
        ' verificare sintassi...[u1,1,64] al posto di [u1,1,#64]
        'itemRead(i) = New Item("/Channel/SelectedFunctions/ncFktAct[u" & i + 1 & ",1," & maxGruppi & "]")  ' leggo TUTTI i gruppi...
      Next i

      'lettura
      Do
        Try
          m_DataSvcRW.Read(itemRead)
          Exit Do
        Catch ex As DataSvcBusyException
          Debug.Print(ex.Message)
        Catch ex As DataSvcException
          Throw New CmsNcException("ERR GetStaticData CNC.SIEMENS DataSvcException", ex)
        End Try
      Loop

      ' faccio copia valori!
      For i As Integer = 0 To maxGruppi - 1
        For j As Integer = 0 To maxProc - 1
          GCodeCurr(j, i) = itemRead(j).Value(i)
        Next j
      Next i

      ' chiudo!
      Return True

    End Function

    'aaIwCorr

    ''' <summary>
    ''' recupera valori posizione xyz ijk
    ''' </summary>
    ''' <param name="maxProc"></param>
    ''' <returns></returns>
    Public Function getPathTTCoord(maxProc As Integer) As PosizLav()

      ' RIFERIMENTO: 
      ' SynumerikOperate_net, pg 52
      ' Parameter manual NC, pg 21
      ' /Channel/State/actFeedRateIpo[u1] pg315


      ReDim itemRead(0)
      'itemRead(0) = New Item("/Channel/GeometricAxis/actToolEdgeCenterPos[u1,1,6]")   'pg 315
      'itemRead(0) = New Item("/Channel/State/acToolOAct[u1,1,6]")   'pg 306 versori 0 0 1 0 0 1?
      'itemRead(0) = New Item("/Channel/State/pToolO[u1,1,6]")   'pg 343
      'itemRead(0) = New Item("/Channel/State/acIwStat[u1,1]")   'pg 290 nada
      itemRead(0) = New Item("/Channel/State/acIwStat[u1,2]")   'pg 290 nada
      ' cmdFeedRateIpo pg 329
      'itemRead(1) = New Item("DB21.DBW158:[36]")   'funzioni estese?!?

      'lettura
      Do
        Try
          m_DataSvcRW.Read(itemRead)
          Exit Do
        Catch ex As DataSvcBusyException
          Debug.Print(ex.Message)
        Catch ex As DataSvcException
          Throw New CmsNcException("ERR GetStaticData CNC.SIEMENS DataSvcException", ex)
        End Try
      Loop

      Dim answ(maxProc) As PosizLav

      For i As Integer = 0 To maxProc - 1
        answ(i).X = 0 ' Convert.ToSingle(itemRead(0).Value)
        answ(i).Y = 0 ' Convert.ToSingle(itemRead(0).Value)
        answ(i).Z = 0 ' Convert.ToSingle(itemRead(0).Value)
        answ(i).I = 0 ' Convert.ToSingle(itemRead(0).Value)
        answ(i).J = 0 ' Convert.ToSingle(itemRead(0).Value)
        answ(i).K = 0 ' Convert.ToSingle(itemRead(0).Value)
      Next i

      Return answ

    End Function

    ''' <summary>
    ''' recupera valori feed/speed
    ''' </summary>
    ''' <param name="maxProc"></param>
    ''' <returns></returns>
    Public Function getAllNcInfo(maxProc As Integer) As FeedSpeedData

      ' RIFERIMENTO: 
      ' SynumerikOperate_net, pg 52
      ' Parameter manual NC, pg 21
      ' /Channel/State/actFeedRateIpo[u1] pg315


      ReDim itemRead(0)
      itemRead(0) = New Item("/Channel/State/cmdFeedRateIpo[u1]")   'pg 315
      ' cmdFeedRateIpo pg 329
      'itemRead(1) = New Item("DB21.DBW158:[36]")   'funzioni estese?!?

      'lettura
      Do
        Try
          m_DataSvcRW.Read(itemRead)
          Exit Do
        Catch ex As DataSvcBusyException
          Debug.Print(ex.Message)
        Catch ex As DataSvcException
          Throw New CmsNcException("ERR GetStaticData CNC.SIEMENS DataSvcException", ex)
        End Try
      Loop

      Dim answ As FeedSpeedData

      answ.Feed = Convert.ToSingle(itemRead(0).Value)

      Return answ

    End Function

    ''' <summary>
    ''' procedura per risposta alla segnalazione di allarmi...
    ''' </summary>
    ''' <param name="guid"></param>
    ''' <param name="alarms"></param>
    Public Sub AlarmList(guid As Guid, alarms() As Alarm)
      ' RIFERIMENTO: 
      ' SynumerikOperate_Net, pg 101 --> 110 (NON serve verifica theread...)

      ' verifico di essere il "corretto responditore"...
      If (m_AlarmGuid.Equals(guid)) Then
        ' salvo nel mio oggetto in memoria...
        currAlarms = alarms
      End If

    End Sub

    Public Function getCncAlarm() As Alarm()
      ' RIFERIMENTO: 
      ' SynumerikOperate_Net, pg 101 --> 110

      ' restituisco vettore allarmi...
      Return currAlarms

    End Function


#End Region

  End Class

End Namespace

#End If