diff --git a/CatiaNetTest/AssemblyTiers2.vb b/CatiaNetTest/AssemblyTiers2.vb
index c9b973ee0a479cad0a94a79ea06162d790cb76bc..0a317b53774e242bd9b2982423dd90f7ca947c31 100644
--- a/CatiaNetTest/AssemblyTiers2.vb
+++ b/CatiaNetTest/AssemblyTiers2.vb
@@ -51,19 +51,9 @@ Public Class AssemblyTiers2
 
     Sub CatMain()
         MsgBox("OK, lets start!")
-        ''Test parameters
-        'iBoundingBoxCode = 1
-        'bBoundingBoxProjectionCheck = True
-        'bConnectivityCheck = False
-        'bAutomaticStep = False
-        'intStep = 5
-        'dCollSens = 2
-        'bChooseExtractionDirection = False
-        ''number of analysed disassembly directions
-        ''6 - only global axes, 12 - including local axes
-        'intJ = 6
+
+        'TODO: Include in Form
         xlsPath = "D:\03_Dissertation\20_Tools\CATIA_NET\ProgData\"
-        'xlsFileName = "Centrifugal pump 5mm step"
 
         CATIA = GetObject(, "CATIA.Application")
         If CATIA Is Nothing Then CATIA = CreateObject("CATIA.Application")
@@ -203,7 +193,7 @@ Public Class AssemblyTiers2
         Debug.Print("Number of faces in assembly: " & CStr(intNumFaces))
 
         'Export BB volumes of parts to Excel
-        'ExportBBVolumes()
+        ExportBBVolumes()
 
         'Collision parameters
         If bAutomaticStep Then
@@ -229,13 +219,6 @@ Public Class AssemblyTiers2
             aRemovalDistances(i, 5) = aAssemblyBoundaries(5) - aPartBBGlob(i, 4)
         Next i
 
-        'MsgBox("Removal distances for " & cRelevantProducts.Item(1).PartNumber & ":" & vbNewLine &
-        '"X_pos = " & aRemovalDistances(0, 0) & vbNewLine &
-        '"X_neg = " & aRemovalDistances(0, 1) & vbNewLine &
-        '"Y_pos = " & aRemovalDistances(0, 2) & vbNewLine &
-        '"Y_neg = " & aRemovalDistances(0, 3) & vbNewLine &
-        '"Z_pos = " & aRemovalDistances(0, 4) & vbNewLine &
-        '"Z_neg = " & aRemovalDistances(0, 5))
 
         '#################### Main algorithm ##########################
 
@@ -438,8 +421,6 @@ entry1:
                                         'if the disassembly tier is 1 lower (attention: tiers get reversed in the end to the assembly tiers!)
                                         If secTier = intTier - 1 And Not (secTier = 0 And intTier = 1) Then
 
-                                            'Debug.Print("Collision with higher tier: " & oConflict1.FirstProduct.Name & " - " & oConflict1.SecondProduct.Name & " = " & oConflict1.Value)
-
                                             'record precedence relation, because secProduct is an obstacle in the way of the current product
                                             precedenceMatrix(int_i, iIndex) = 1
 
@@ -680,19 +661,11 @@ exitCD:
                 Next intAxis
                 'Only for products with multiple extraction directions
                 If sum > 1 Then
-                    'Add options to ComboBox
-                    For intAxis = 0 To intJ - 1
-                        If disassDir(int_i, intAxis) = 1 Then
-                            'ExtractionDirection.ComboBox1.AddItem(d1.Item(intAxis))
-                        End If
-                    Next intAxis
                     'Highlight the product in CATIA
                     Dim selection5 As Selection
                     selection5 = CATIA.ActiveDocument.Selection
                     selection5.Clear()
                     selection5.Add(cRelevantProducts.Item(int_i + 1))
-                    'Show dialog
-                    'ExtractionDirection.Show
                     selection5.Clear()
                     'Translate chosen axis name back into index 0..11
                     Dim iChosenDir As Integer
@@ -884,6 +857,7 @@ exitCD:
         End If
 
     End Function
+
     Sub Liaison()
 
         Dim n As Integer = cRelevantProducts.Count
@@ -1048,15 +1022,6 @@ exitCD:
                 CATIA.StartCommand("Activate / Deactivate Component")
                 selection1.Clear()
                 intFasteners = intFasteners + 1
-                'ElseIf InStr(sName, "pin") > 0 Then
-                '    Debug.Print(prod.Name + " was identified as a pin")
-                '    selection1.Add(prod)
-
-                '    primaryFasteners.Add(prod)
-
-                '    CATIA.StartCommand("Activate / Deactivate Component")
-                '    selection1.Clear()
-                '    intFasteners = intFasteners + 1
             ElseIf InStr(sName, "nut") > 0 Or (InStr(sName, "iso") > 0 And InStr(sName, "4161") > 0) Or (InStr(sName, "din") > 0 And (InStr(sName, "934") > 0 Or InStr(sName, "439") > 0)) Then
                 Debug.Print(prod.Name + " was identified as a nut")
                 selection1.Add(prod)
@@ -1080,7 +1045,6 @@ exitCD:
             End If
         Next
 
-        'CATIA.StartCommand ("Activate / Deactivate Component")
         Debug.Print("Deactivated " + CStr(intFasteners) + " fasteners")
         intParts = intParts - intFasteners
         Debug.Print(CStr(intParts) + " parts to assemble")
@@ -1142,7 +1106,6 @@ exitCD:
 
             Dim originpoint As HybridShapePointCoord
             axissyst.GetOrigin(originCoord)
-            'MsgBox "X0 = " & CStr(originCoord(0)) & vbNewLine & "Y0 = " & CStr(originCoord(1)) & vbNewLine & "Z0 = " & CStr(originCoord(2))
 
             originpoint = hybridShapeFactory1.AddNewPointCoord(originCoord(0), originCoord(1), originCoord(2))
             axisref = part1.CreateReferenceFromObject(originpoint)
@@ -1244,7 +1207,6 @@ exitCD:
                 part1.UpdateObject(HybridShapeExtremum5)
                 part1.UpdateObject(HybridShapeExtremum6)
 
-                'part1.Update
 
                 ' Creates a 6 single points using the Extrenums as refs, so if the Extrenum was a line or surf, you can still off planes to these points
 
@@ -1303,8 +1265,6 @@ exitCD:
                 part1.UpdateObject(Point5)
                 part1.UpdateObject(Point6)
 
-                'part1.Update
-
                 axissyst.IsCurrent = 1
 
                 'Read extremum coordinates
@@ -1497,14 +1457,6 @@ exitCD:
 
     End Sub
 
-    'Public Function ArrayLen(a As Object) As Integer
-    '    If IsEmpty(a) Then
-    '        ArrayLen = 0
-    '    Else
-    '        ArrayLen = UBound(a) - LBound(a) + 1
-    '    End If
-    'End Function
-
     Function Det3x3(dX11 As Double, dX12 As Double, dX13 As Double,
                 dX21 As Double, dX22 As Double, dX23 As Double,
                 dX31 As Double, dX32 As Double, dX33 As Double) As Double
@@ -1707,22 +1659,9 @@ exitCD:
     End Sub
 
     Function collisionDetected(cClashes As Clashes, group1 As Group, group2 As Group) As Boolean
-        'cRelevantProducts As Collection, cDeactivated As Collection
 
         collisionDetected = False
 
-        'define two groups
-        '    Dim group1 As Group
-        'Dim group2 As Group
-        '     group1 = cGroups.Add
-        ' group2 = cGroups.Add
-        '    group1.AddExplicit product1
-        '    Dim relevantProduct As Product
-        '    For Each relevantProduct In cRelevantProducts
-        '      If Not relevantProduct.Name = product1.Name And Not productIsInCollection(relevantProduct, cDeactivated) Then
-        '        group2.AddExplicit relevantProduct
-        '      End If
-        '    Next relevantProduct
         'create a new clash analysis
         Dim oClash As Clash
         oClash = cClashes.Add
@@ -1730,12 +1669,10 @@ exitCD:
         oClash.FirstGroup = group1
         oClash.SecondGroup = group2
         oClash.InterferenceType = SPATypeLib.CatClashInterferenceType.catClashInterferenceTypeClearance
-        'oClash.Clearance = dCollSens
         oClash.Compute()
         Dim cConflicts As Conflicts
         cConflicts = oClash.Conflicts
         If cConflicts.Count > 0 Then
-            'MsgBox "Detected a collision: " & product1.Name
             'If at least one conflict value exceeds the collision sensitivity, it is a collision
             Dim oConflict As Conflict
             Dim c As Integer
@@ -1745,7 +1682,6 @@ exitCD:
                 If oConflict.Type = SPATypeLib.CatConflictType.catConflictTypeClash Then
                     If oConflict.Value < -dCollSens Then
                         collisionDetected = True
-                        'Debug.Print("Clash detected: " & oConflict.FirstProduct.Name & " - " & oConflict.SecondProduct.Name & " = " & oConflict.Value)
                         Exit For
                     End If
                 End If
@@ -1761,27 +1697,21 @@ exitCD:
         oPosition.GetComponents(posArray)
         If posArray(9) > aRemovalDistances(i1, 0) Then
             productReachedFinalPosition = True
-            'MsgBox "X+ removal distance reached by " & objProd.Name
         End If
         If posArray(9) < aRemovalDistances(i1, 1) Then
             productReachedFinalPosition = True
-            'MsgBox "X- removal distance reached by " & objProd.Name
         End If
         If posArray(10) > aRemovalDistances(i1, 2) Then
             productReachedFinalPosition = True
-            'MsgBox "Y+ removal distance reached by " & objProd.Name
         End If
         If posArray(10) < aRemovalDistances(i1, 3) Then
             productReachedFinalPosition = True
-            'MsgBox "Y- removal distance reached by " & objProd.Name
         End If
         If posArray(11) > aRemovalDistances(i1, 4) Then
             productReachedFinalPosition = True
-            'MsgBox "Z+ removal distance reached by " & objProd.Name
         End If
         If posArray(11) < aRemovalDistances(i1, 5) Then
             productReachedFinalPosition = True
-            'MsgBox "Z- removal distance reached by " & objProd.Name
         End If
     End Function
 
@@ -1828,16 +1758,11 @@ exitCD:
         oCurrentProd = oCurrentProd.ReferenceProduct    'You have to work with the "ReferenceProduct" object
         lNumberOfItems = oCurrentProd.Products.Count
 
-        'For i = 1 To lNumberOfItems                         'Clear out the rename array
-        '    RenameArray(i) = ""                             'Don't know if this is necessary
-        'Next
-
         'Run through this loop once, to set everything to a dummy name, to avoid naming conflicts
         For i = 1 To lNumberOfItems                             'Cycle through the assembly's children
             ItemToRename = oCurrentProd.Products.Item(i)    'Declare which item we are working on
 
             ToRenamePartNumber = ItemToRename.PartNumber        'Get the Part Number
-            'ToRenamePartNumber = ItemToRename.DescriptionRef   'Toggle these two lines for testing
 
             RenameArray(i) = ToRenamePartNumber                 'Building the list of part names for the numbering loop
 
@@ -1848,7 +1773,6 @@ exitCD:
                 End If
             Next
             CATIA.StatusBar = ItemToRename.Name & " > " & ToRenamePartNumber & "." & k
-            'MsgBox ItemToRename.Name & " / " & ToRenamePartNumber & "." & k    'This line is for testing only
             ItemToRename.Name = ToRenamePartNumber & "TEMP." & k    'Set the new instance name, to a TEMP dummy value
 
         Next
@@ -1858,7 +1782,6 @@ exitCD:
             ItemToRename = oCurrentProd.Products.Item(i)
 
             ToRenamePartNumber = ItemToRename.PartNumber        'Toggle these two lines for testing
-            'ToRenamePartNumber = ItemToRename.DescriptionRef   'Toggle these two lines for testing
 
             RenameArray(i) = ToRenamePartNumber
 
@@ -1870,7 +1793,6 @@ exitCD:
             Next
 
             CATIA.StatusBar = ItemToRename.Name & " > " & ToRenamePartNumber & "." & k
-            'MsgBox ItemToRename.Name & " / " & ToRenamePartNumber & "." & k    'For testing
 
             ItemToRename.Name = ToRenamePartNumber & "." & k    'Set the new instance name final
 
@@ -1942,7 +1864,6 @@ Finish:
             Do
                 intRel = System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
             Loop While intRel > 0
-            'MsgBox("Final Released obj # " & intRel)
         Catch ex As Exception
             MsgBox("Error releasing object" & ex.ToString)
             obj = Nothing
@@ -1953,12 +1874,10 @@ Finish:
 
     Sub ShowForm()
         'Create a new form to input algorithm specifications first
-        'Dim Form2 As Form = New Form()
         Me.Text = "Algorithm specifications"
         Me.Size = New System.Drawing.Size(350, 400)
         'Create elements for parameter inputs
         'Code variant for BB calculation
-        'Dim BBCodeComboBox As ComboBox = New ComboBox()
         BBCodeComboBox.Items.Add(1)
         BBCodeComboBox.Items.Add(2)
         BBCodeComboBox.Location = New System.Drawing.Point(200, 20)
@@ -1969,28 +1888,24 @@ Finish:
         Label1.Location = New System.Drawing.Point(20, 20)
         Label1.Size = New System.Drawing.Size(150, 20)
         'Projection check
-        'Dim BBPCCheckBox As System.Windows.Forms.CheckBox = New System.Windows.Forms.CheckBox()
         BBPCCheckBox.Location = New System.Drawing.Point(200, 50)
         Dim Label2 As System.Windows.Forms.Label = New System.Windows.Forms.Label()
         Label2.Text = "BB projection check"
         Label2.Location = New System.Drawing.Point(20, 50)
         Label2.Size = New System.Drawing.Size(150, 20)
         'Connectivity check
-        'Dim CCCheckBox As System.Windows.Forms.CheckBox = New System.Windows.Forms.CheckBox()
         CCCheckBox.Location = New System.Drawing.Point(200, 80)
         Dim Label3 As System.Windows.Forms.Label = New System.Windows.Forms.Label()
         Label3.Text = "Connectivity check"
         Label3.Location = New System.Drawing.Point(20, 80)
         Label3.Size = New System.Drawing.Size(150, 20)
         'Automatic step
-        'Dim AutoStepCheckBox As System.Windows.Forms.CheckBox = New System.Windows.Forms.CheckBox()
         AutoStepCheckBox.Location = New System.Drawing.Point(200, 110)
         Dim Label4 As System.Windows.Forms.Label = New System.Windows.Forms.Label()
         Label4.Text = "Automatic step"
         Label4.Location = New System.Drawing.Point(20, 110)
         Label4.Size = New System.Drawing.Size(150, 20)
         'Step
-        'Dim StepTextBox As System.Windows.Forms.TextBox = New System.Windows.Forms.TextBox()
         StepTextBox.Text = 5
         StepTextBox.Location = New System.Drawing.Point(200, 140)
         StepTextBox.Size = New System.Drawing.Size(50, 20)
@@ -1999,7 +1914,6 @@ Finish:
         Label5.Location = New System.Drawing.Point(20, 140)
         Label5.Size = New System.Drawing.Size(150, 20)
         'Collision sensitivity
-        'Dim CollSensTextBox As System.Windows.Forms.TextBox = New System.Windows.Forms.TextBox()
         CollSensTextBox.Text = 2
         CollSensTextBox.Location = New System.Drawing.Point(200, 170)
         CollSensTextBox.Size = New System.Drawing.Size(50, 20)
@@ -2008,14 +1922,12 @@ Finish:
         Label6.Location = New System.Drawing.Point(20, 170)
         Label6.Size = New System.Drawing.Size(150, 20)
         'Choice of extraction direction
-        'Dim ExtractDirCheckBox As System.Windows.Forms.CheckBox = New System.Windows.Forms.CheckBox()
         ExtractDirCheckBox.Location = New System.Drawing.Point(200, 200)
         Dim Label7 As System.Windows.Forms.Label = New System.Windows.Forms.Label()
         Label7.Text = "Choice of disassembly axis"
         Label7.Location = New System.Drawing.Point(20, 200)
         Label7.Size = New System.Drawing.Size(150, 20)
         'Number of disassembly axis
-        'Dim AxisComboBox As ComboBox = New ComboBox()
         AxisComboBox.Items.Add(6)
         AxisComboBox.Items.Add(12)
         AxisComboBox.Location = New System.Drawing.Point(200, 230)
@@ -2026,7 +1938,6 @@ Finish:
         Label8.Location = New System.Drawing.Point(20, 230)
         Label8.Size = New System.Drawing.Size(150, 20)
         'Desired name of the output Excel file
-        'Dim XLSTextBox As System.Windows.Forms.TextBox = New System.Windows.Forms.TextBox()
         XLSTextBox.Text = "Product"
         XLSTextBox.Location = New System.Drawing.Point(200, 260)
         Dim Label9 As System.Windows.Forms.Label = New System.Windows.Forms.Label()
@@ -2034,7 +1945,6 @@ Finish:
         Label9.Location = New System.Drawing.Point(20, 260)
         Label9.Size = New System.Drawing.Size(150, 20)
         'OK button
-        'Dim OKButton As System.Windows.Forms.Button = New System.Windows.Forms.Button()
         OKButton.Text = "Accept parameters"
         OKButton.Location = New System.Drawing.Point(100, 310)
         OKButton.Size = New System.Drawing.Size(150, 40)
diff --git a/CatiaNetTest/AssemblyTiers3.vb b/CatiaNetTest/AssemblyTiers3.vb
deleted file mode 100644
index b74642a28f56bcc15df799a5877c42e967f21313..0000000000000000000000000000000000000000
--- a/CatiaNetTest/AssemblyTiers3.vb
+++ /dev/null
@@ -1,2027 +0,0 @@
-Imports System
-Imports HybridShapeTypeLib
-Imports INFITF
-Imports MECMOD
-Imports NavigatorTypeLib
-Imports ProductStructureTypeLib
-Imports SPATypeLib
-Imports PARTITF
-Imports Microsoft.Office.Interop.Excel
-
-Public Class AssemblyTiers3
-    Inherits Form
-
-    Friend WithEvents OKButton As System.Windows.Forms.Button = New System.Windows.Forms.Button()
-    Friend WithEvents BBCodeComboBox As System.Windows.Forms.ComboBox = New ComboBox()
-    Friend WithEvents BBPCCheckBox As System.Windows.Forms.CheckBox = New System.Windows.Forms.CheckBox()
-    Friend WithEvents CCCheckBox As System.Windows.Forms.CheckBox = New System.Windows.Forms.CheckBox()
-    Friend WithEvents AutoStepCheckBox As System.Windows.Forms.CheckBox = New System.Windows.Forms.CheckBox()
-    Friend WithEvents StepTextBox As System.Windows.Forms.TextBox = New System.Windows.Forms.TextBox()
-    Friend WithEvents CollSensTextBox As System.Windows.Forms.TextBox = New System.Windows.Forms.TextBox()
-    Friend WithEvents ExtractDirCheckBox As System.Windows.Forms.CheckBox = New System.Windows.Forms.CheckBox()
-    Friend WithEvents AxisComboBox As System.Windows.Forms.ComboBox = New System.Windows.Forms.ComboBox()
-    Friend WithEvents XLSTextBox As System.Windows.Forms.TextBox = New System.Windows.Forms.TextBox()
-
-    Public bConnectivityCheck As Boolean
-    Public bBoundingBoxProjectionCheck As Boolean
-    Public bAutomaticStep As Boolean
-    Public bChooseExtractionDirection As Boolean
-    Public intJ As Integer
-    Public iBoundingBoxCode As Integer
-    Public intStep As Integer
-    Public dCollSens As Double
-    Public xlsPath As String
-    Public xlsFileName As String
-    Public intParts As Integer
-    Public intNumFaces As Integer
-    Public primaryFasteners As New ArrayList
-    Public secondaryFasteners As New ArrayList
-    Public cAllProducts As New ArrayList
-    Public cRelevantProducts As New ArrayList
-    Public cBaseProducts As New ArrayList
-    Public aRemovalDistances(,) As Double
-    Public aAssemblyBoundaries(5) As Double
-    Public aPartBBGlob(,) As Double
-    Public aInitPos(,) As Double
-    Public liaisonMatrix(,) As Integer
-    Public sChosenDirection As String
-    Public oList As Object
-    Public CATIA As INFITF.Application
-
-
-    Sub CatMain()
-
-        ''Test parameters
-        'iBoundingBoxCode = 1
-        'bBoundingBoxProjectionCheck = True
-        'bConnectivityCheck = False
-        'bAutomaticStep = False
-        'intStep = 5
-        'dCollSens = 2
-        'bChooseExtractionDirection = False
-        ''number of analysed disassembly directions
-        ''6 - only global axes, 12 - including local axes
-        'intJ = 6
-        xlsPath = "D:\03_Dissertation\20_Tools\CATIA_NET\ProgData"
-        'xlsFileName = "Centrifugal pump 5mm step"
-
-        CATIA = GetObject(, "CATIA.Application")
-        If CATIA Is Nothing Then CATIA = CreateObject("CATIA.Application")
-
-        Debug.Print("========================================================")
-
-        Dim document As ProductDocument
-        document = CATIA.ActiveDocument
-
-        'Extraction of all "leaf" products to cAllProducts
-        ExtractProducts(document.Product)
-
-        'Collection of "leaf" Products (without nested Products)
-        Dim oInstances As New ArrayList
-        oInstances = cAllProducts
-        Dim i As Integer
-        Dim outputText As String
-
-        intParts = oInstances.Count
-        outputText = "This assembly contains " + CStr(intParts) + " parts" + vbNewLine
-        MsgBox(outputText)
-
-        'Select the assembly's base components
-        'Declare selection
-        Dim oSel As Selection
-        Dim baseSel As Object  'to deal with restricted function problem
-        oSel = CATIA.ActiveDocument.Selection
-        baseSel = oSel
-        'Create an array for CATParts
-        Dim strArray(0)
-        strArray(0) = "Part"
-        'Display a messagebox prompting the user to select CATIA parts
-        MsgBox("Please select the assembly's base components")
-        Dim sStatus As String
-        sStatus = baseSel.SelectElement3(strArray, "Select parts", False, INFITF.CATMultiSelectionMode.CATMultiSelTriggWhenUserValidatesSelection, False)
-
-        For i = 1 To baseSel.Count
-            cBaseProducts.Add(baseSel.Item(i).LeafProduct)
-            Debug.Print("Added base component: " & baseSel.Item(i).LeafProduct.Name)
-        Next
-
-        oSel.Clear()
-        baseSel.Clear
-
-        'Separation of components
-        DeactivateFasteners(document.Product)
-
-        'Display the number of relevant parts
-        outputText = CStr(cRelevantProducts.Count) + " parts are considered in precedence graph generation"
-        MsgBox(outputText)
-
-        'Distances from global axis system origin to assembly boundary (along global axis)
-        aAssemblyBoundaries(0) = -1 / 0     'max_X
-        aAssemblyBoundaries(1) = 1 / 0      'min_X
-        aAssemblyBoundaries(2) = -1 / 0     'max_Y
-        aAssemblyBoundaries(3) = 1 / 0      'min_Y
-        aAssemblyBoundaries(4) = -1 / 0     'max_Z
-        aAssemblyBoundaries(5) = 1 / 0      'min_Z
-
-        'Global coordinates, of which at least one has to be exceeded by the part origin, for that part to be "disassembled"
-        'in global axis directions
-        ReDim aRemovalDistances(cRelevantProducts.Count - 1, 5)
-        aRemovalDistances(0, 0) = 0#     'X_pos
-        aRemovalDistances(0, 1) = 0#     'X_neg
-        aRemovalDistances(0, 2) = 0#     'Y_pos
-        aRemovalDistances(0, 3) = 0#     'Y_neg
-        aRemovalDistances(0, 4) = 0#     'Z_pos
-        aRemovalDistances(0, 5) = 0#     'Z_neg
-
-        'Store information about secondary BB (6 distances to boundary planes from part origin along global x/y/z directions) - used to define aRemovalDistances
-        'Secondary BB: faces parallel to global origin planes and defined by outermost corner points of local BB of this part
-        ReDim aPartBBGlob(cRelevantProducts.Count - 1, 5)
-        aPartBBGlob(0, 0) = 0#           'x_part_glob_pos
-        aPartBBGlob(0, 1) = 0#           'x_part_glob_neg
-        aPartBBGlob(0, 2) = 0#           'y_part_glob_pos
-        aPartBBGlob(0, 3) = 0#           'y_part_glob_neg
-        aPartBBGlob(0, 4) = 0#           'z_part_glob_pos
-        aPartBBGlob(0, 5) = 0#           'z_part_glob_neg
-
-        'Initialize aPartBBGlob with safe values
-        For i = 0 To cRelevantProducts.Count - 1
-            aPartBBGlob(i, 0) = -1 / 0
-            aPartBBGlob(i, 1) = 1 / 0
-            aPartBBGlob(i, 2) = -1 / 0
-            aPartBBGlob(i, 3) = 1 / 0
-            aPartBBGlob(i, 4) = -1 / 0
-            aPartBBGlob(i, 5) = 1 / 0
-        Next
-
-        Dim BBStartTime As DateTime
-        BBStartTime = Now
-
-        'This is used to check whether a product must be moved in current iteration
-        Dim bMoveable(cRelevantProducts.Count - 1) As Boolean
-
-        'Number of faces in assembly represents the geometrical complexity of parts
-        intNumFaces = 0
-
-        For i = 0 To cRelevantProducts.Count - 1
-            Dim prodI As Product
-            If iBoundingBoxCode = 1 Then
-                'this won't work if part document name is not = part number
-                prodI = cRelevantProducts.Item(i)
-                Dim docName As String
-                docName = prodI.PartNumber + ".CATPart"
-                Debug.Print(">>> " & docName & " <<<")
-                GenerateBoundingBox(CATIA.Documents.Item(docName), prodI, i)
-            ElseIf iBoundingBoxCode = 2 Then
-                prodI = cRelevantProducts.Item(i)
-                Dim docName As String
-                docName = prodI.PartNumber + ".CATPart"
-                Dim oPartDoc As PartDocument
-                Dim sPartPath As String
-                sPartPath = prodI.GetMasterShapeRepresentationPathName
-                oPartDoc = CATIA.Documents.Read(sPartPath)
-                Debug.Print(">>> " & docName & " <<<")
-                'CATIA.Documents.Item(docName)
-                GenerateBoundingBox(oPartDoc, prodI, i)
-            Else
-                Debug.Print("Allowed bounding box code type are 1 and 2!")
-            End If
-
-            'Base component is in cRelevantProducts, but not moveable
-            If productIsInCollection(prodI, cBaseProducts) Then
-                bMoveable(i) = False
-            Else
-                bMoveable(i) = True
-            End If
-
-        Next i
-
-        Dim BBMillisecondsElapsed As Double
-        BBMillisecondsElapsed = (Now - BBStartTime).TotalMilliseconds
-        Dim BBSecondsElapsed As Double
-        BBSecondsElapsed = Math.Round(BBMillisecondsElapsed / 1000.0, 2)
-        MsgBox("Bounding box calculation took " & CStr(BBSecondsElapsed) & " seconds")
-        Debug.Print("Number of faces in assembly: " & CStr(intNumFaces))
-
-        'Export BB volumes of parts to Excel
-        ExportBBVolumes()
-
-        'Collision parameters
-        If bAutomaticStep Then
-            Dim dGeomMean As Double
-            dGeomMean = (aAssemblyBoundaries(0) - aAssemblyBoundaries(1)) * (aAssemblyBoundaries(2) - aAssemblyBoundaries(3)) * (aAssemblyBoundaries(4) - aAssemblyBoundaries(5))
-            dGeomMean = dGeomMean ^ (1 / 3)
-            intStep = Math.Round(dGeomMean / 50, 0)
-        End If
-        Debug.Print("Movement step: " & CStr(intStep))
-
-        MsgBox("Assembly dimensions: " & vbNewLine &
-        "X = " & aAssemblyBoundaries(0) - aAssemblyBoundaries(1) & vbNewLine &
-        "Y = " & aAssemblyBoundaries(2) - aAssemblyBoundaries(3) & vbNewLine &
-        "Z = " & aAssemblyBoundaries(4) - aAssemblyBoundaries(5))
-
-        'After the aAssemblyBoundaries and aPartBBGlob are calculated, define aRemovalDistances
-        For i = 0 To cRelevantProducts.Count - 1
-            aRemovalDistances(i, 0) = aAssemblyBoundaries(0) - aPartBBGlob(i, 1)
-            aRemovalDistances(i, 1) = aAssemblyBoundaries(1) - aPartBBGlob(i, 0)
-            aRemovalDistances(i, 2) = aAssemblyBoundaries(2) - aPartBBGlob(i, 3)
-            aRemovalDistances(i, 3) = aAssemblyBoundaries(3) - aPartBBGlob(i, 2)
-            aRemovalDistances(i, 4) = aAssemblyBoundaries(4) - aPartBBGlob(i, 5)
-            aRemovalDistances(i, 5) = aAssemblyBoundaries(5) - aPartBBGlob(i, 4)
-        Next i
-
-        'MsgBox("Removal distances for " & cRelevantProducts.Item(1).PartNumber & ":" & vbNewLine &
-        '"X_pos = " & aRemovalDistances(0, 0) & vbNewLine &
-        '"X_neg = " & aRemovalDistances(0, 1) & vbNewLine &
-        '"Y_pos = " & aRemovalDistances(0, 2) & vbNewLine &
-        '"Y_neg = " & aRemovalDistances(0, 3) & vbNewLine &
-        '"Z_pos = " & aRemovalDistances(0, 4) & vbNewLine &
-        '"Z_neg = " & aRemovalDistances(0, 5))
-
-        '#################### Main algorithm ##########################
-
-        Dim intI As Integer                   'total number of components in the scene minus base parts
-        Dim intTier As Integer                'number of current assembly tier
-        Dim int_i As Integer                  'product index in cRelevantProducts
-        Dim int_i_cycle As Integer            'product counter
-        Dim int_j As Integer                  'primary direction index 1..12
-        Dim int_j_temp As Integer             'used to display movement direction once
-        Dim int_k As Integer                  'secondary direction index 1..10
-        Dim total_coll As Long                'counter of total collision detections
-        Dim cDeactivated As New ArrayList    'really deactivated products
-        Dim cVirtual As Collection        'these funny green parts
-        Dim precedenceMatrix(cRelevantProducts.Count - 1, cRelevantProducts.Count - 1) As Single
-        Dim disassDir(cRelevantProducts.Count - 1, 11)
-        Dim aTiers(cRelevantProducts.Count - 1) As Integer
-        ReDim aInitPos(cRelevantProducts.Count - 1, 11)     'remember initial positions of the products
-        Dim bInitPosRecorded(cRelevantProducts.Count - 1) As Boolean
-        Dim bDeactivated(cRelevantProducts.Count - 1) As Boolean
-        Dim bDisassembled(cRelevantProducts.Count - 1) As Boolean
-
-        For i = 0 To cRelevantProducts.Count - 1
-            If intJ = 6 Then
-                For j = 0 To 5
-                    disassDir(i, j) = 1
-                Next
-            End If
-            If intJ = 12 Then
-                For j = 0 To 11
-                    disassDir(i, j) = 1
-                Next
-            End If
-        Next
-
-        'Before trying to remove a component, check whether it would break liaison graph connectivity
-        Dim connectivityCheckNodeIndices As New List(Of Integer)
-        If bConnectivityCheck Then
-            Dim componentIndex As Integer
-            componentIndex = 0
-            For Each oComponent In cRelevantProducts
-                connectivityCheckNodeIndices.Add(componentIndex)
-                componentIndex = componentIndex + 1
-            Next oComponent
-            'Liaison graph extraction for connectivity checks
-            Liaison()
-        End If
-
-        intI = cRelevantProducts.Count   'the index of base components will be simply skipped (cRelevantProducts includes cBaseProducts, unlike in the paper!)
-        intTier = 1                       'counts current disassembly tier (lower number means earlier disassembly possible) - this gets reversed in the end
-        int_i = 0                         'index of current part in collection of relevant products
-        int_i_cycle = 0                   'counter for the current tier iteration
-        int_j = 0                         'index of disassembly direction
-        int_j_temp = -1                    'used to display movement direction once
-        total_coll = 0
-
-        'map indices to directions (careful, starts from 0 here, but the paper and moveProduct uses 1 as start)
-        Dim d1
-        d1 = CreateObject("Scripting.Dictionary")
-        d1.Add(0, "Global X+")
-        d1.Add(1, "Global Y+")
-        d1.Add(2, "Global Z+")
-        d1.Add(3, "Global X-")
-        d1.Add(4, "Global Y-")
-        d1.Add(5, "Global Z-")
-        d1.Add(6, "Local X+")
-        d1.Add(7, "Local Y+")
-        d1.Add(8, "Local Z+")
-        d1.Add(9, "Local X-")
-        d1.Add(10, "Local Y-")
-        d1.Add(11, "Local Z-")
-
-        'access the clash technology object
-        Dim cClashes As Clashes
-        cClashes = CATIA.ActiveDocument.Product.GetTechnologicalObject("Clashes")
-        'access the groups technology object
-        Dim cGroups As Groups
-        cGroups = CATIA.ActiveDocument.Product.GetTechnologicalObject("Groups")
-
-        Dim AssemblyTiersStartTime As DateTime
-        AssemblyTiersStartTime = Now
-
-        While intI > cBaseProducts.Count    'tier loop
-            While int_i_cycle < intI - cBaseProducts.Count  'part loop
-                'Processing next Product
-                Dim product1 As Product
-                product1 = cRelevantProducts.Item(int_i)
-                'Remember initial position P_i (initPos)
-                Dim initPos(11)
-                If bInitPosRecorded(int_i) = False Then
-                    Dim oPosition1 As Object
-                    oPosition1 = product1.Position
-                    oPosition1.GetComponents(initPos)
-                    Dim ip As Integer
-                    For ip = 0 To 11
-                        aInitPos(int_i, ip) = initPos(ip)
-                    Next ip
-                    bInitPosRecorded(int_i) = True
-                End If
-                If bMoveable(int_i) = True Then
-                    Debug.Print("[tier=" & intTier & ", i_cycle=" & int_i_cycle & ", I=" & intI & "] Processing part: " & product1.Name)
-                    Dim connected As Boolean
-                    connected = False
-                    If bConnectivityCheck = True Then
-                        Dim listIndex As Integer
-                        listIndex = 0
-                        For Each partIndex In connectivityCheckNodeIndices
-                            If partIndex = int_i Then
-                                Exit For
-                            Else
-                                listIndex = listIndex + 1
-                            End If
-                        Next
-                        connectivityCheckNodeIndices.RemoveAt(listIndex)
-                        'Check whether all node of LG can be visited from any other node (= connected graph)
-                        If SubassemblyIsConnected(connectivityCheckNodeIndices) Then
-                            'Put int_i back at listIndex
-                            connectivityCheckNodeIndices.Insert(listIndex, int_i)
-                            connected = True
-                        Else
-                            'If connectivity will be broken, skip this component
-                            Debug.Print("Removing " & product1.Name & " would violate liaison graph connectivity!")
-                            'Put int_i back at listIndex
-                            connectivityCheckNodeIndices.Insert(listIndex, int_i)
-                        End If
-                    Else 'no connectivity check, connectivity is assumed to hold
-                        connected = True
-                    End If
-                    If connected = True Then
-                        'Group that includes our product (needed for collision detection between two selections or groups)
-                        Dim group1 As Group
-                        group1 = cGroups.Add
-                        group1.AddExplicit(product1)
-                        'Create a Group of Products that this product shouldn't collide with
-                        Dim group2 As Group
-                        group2 = cGroups.Add
-                        Dim iStaticProduct As Integer
-                        For iStaticProduct = 0 To cRelevantProducts.Count - 1
-                            If iStaticProduct <> int_i And Not bDeactivated(iStaticProduct) Then
-                                If bBoundingBoxProjectionCheck Then
-                                    If BoundingBoxesOverlap(int_i, iStaticProduct) Then
-                                        group2.AddExplicit(cRelevantProducts.Item(iStaticProduct))
-                                    End If
-                                Else
-                                    group2.AddExplicit(cRelevantProducts.Item(iStaticProduct))
-                                End If
-                            End If
-                        Next iStaticProduct
-                        While int_j < intJ  'direction loop
-                            While productReachedFinalPosition(product1, int_i) = False 'movement loop
-                                moveProduct(product1, int_j, True)
-                                If productReachedFinalPosition(product1, int_i) = True Then
-                                    bDisassembled(int_i) = True
-                                    disassDir(int_i, int_j) = 1
-                                    Debug.Print("Successful disassembly: [" & d1.Item(int_j) & "]")
-                                End If
-                                If collisionDetected(cClashes, group1, group2) = True Then
-                                    'check for collisions with higher tier
-                                    Dim detConflicts As Conflicts
-                                    detConflicts = cClashes.Item(cClashes.Count).Conflicts
-                                    If detConflicts.Count > 0 Then
-                                        Dim oConflict1 As Conflict
-                                        Dim ic As Integer
-                                        For ic = 1 To detConflicts.Count
-                                            oConflict1 = detConflicts.Item(ic)
-                                            oConflict1.Status = SPATypeLib.CatConflictStatus.catConflictStatusRelevant
-                                            If oConflict1.Type = SPATypeLib.CatConflictType.catConflictTypeClash Then
-                                                If oConflict1.Value < -dCollSens Then
-                                                    Dim secProduct As Product
-                                                    'get the product we collided with
-                                                    secProduct = oConflict1.SecondProduct
-                                                    'find the tier of the second product
-                                                    Dim dummyProd As Product
-                                                    Dim iIndex As Integer
-                                                    iIndex = 0
-                                                    For Each dummyProd In cRelevantProducts
-                                                        If dummyProd.Name = secProduct.Name Then
-                                                            Exit For
-                                                        End If
-                                                        iIndex = iIndex + 1
-                                                    Next dummyProd
-                                                    Dim secTier As Integer
-                                                    secTier = aTiers(iIndex)
-                                                    'as soon as secTier is not the direct higher tier, no reason to move further
-                                                    If secTier < intTier - 1 Or (intTier = 1 And secTier = 0) Then
-                                                        disassDir(int_i, int_j) = 0
-                                                        Exit While
-                                                    End If
-                                                    'if the disassembly tier is 1 lower (attention: tiers get reversed in the end to the assembly tiers!)
-                                                    If secTier = intTier - 1 And Not intTier = 1 Then
-                                                        'Debug.Print("Collision with higher tier: " & oConflict1.FirstProduct.Name & " - " & oConflict1.SecondProduct.Name & " = " & oConflict1.Value)
-                                                        'record precedence relation, because secProduct is an obstacle in the way of the current product
-                                                        precedenceMatrix(int_i, iIndex) = 1
-                                                        'move the product through the "virtual" part from higher tier
-                                                    End If
-                                                End If  'deeper than dCollSens
-                                            End If    'clash
-                                        Next ic 'next conflict
-                                    End If
-                                End If
-                            End While 'movement loop
-                            'move product to initial position
-                            Dim oPosition4 As Object
-                            oPosition4 = product1.Position
-                            oPosition4.SetComponents(initPos)
-                            'take next direction
-                            int_j += 1
-                        End While 'direction loop
-                        'if this component can be disassembled, remove its index from connectivity check list
-                        If bConnectivityCheck And bDisassembled(int_i) Then
-                            Dim listInd As Integer
-                            listInd = 0
-                            For Each partIndex In connectivityCheckNodeIndices
-                                If partIndex = int_i Then
-                                    Exit For
-                                Else
-                                    listInd = listInd + 1
-                                End If
-                            Next partIndex
-                            'Remove int_i from index list (only after all directions were checked)
-                            connectivityCheckNodeIndices.RemoveAt(listInd)
-                        End If
-                    End If
-                    int_i_cycle += 1
-                Else
-                    'base component or deactivated
-                    Debug.Print("Skipping " + product1.Name + " (base component or deactivated)")
-                End If
-                int_i += 1
-                int_j = 0
-            End While 'part loop
-
-            Dim p As Integer
-            Dim intItemp As Integer
-            intItemp = intI
-            'record tiers
-            For p = 0 To cRelevantProducts.Count - 1
-                If productIsInCollection(cRelevantProducts.Item(p), cBaseProducts) Then
-                    'base product always has tier 0 (doesn't get reversed)
-                    aTiers(p) = 0
-                Else
-                    'not a base product
-                    'product has valid disass. directions and has no tier recorded yet
-                    If bDisassembled(p) = True And Not aTiers(p) > 0 Then
-                        'save tier
-                        aTiers(p) = intTier
-                        'decrease the counter of active products in assembly
-                        intI = intI - 1
-                        'change visuals for "virtual" products
-                        Dim virtSelection As Selection
-                        virtSelection = document.Selection
-                        virtSelection.Clear()
-                        virtSelection.Add(cRelevantProducts.Item(p))
-                        Dim visProperties1 As Object
-                        visProperties1 = virtSelection.VisProperties
-                        visProperties1.SetRealColor(80, 255, 160, 1)
-                        virtSelection.Clear()
-                        'remember virtual green products
-                        'cVirtual.Add cRelevantProducts.Item(p)
-                        'fix position
-                        bMoveable(p) = False
-
-                    End If
-                    'product from higher tier
-                    If bDisassembled(p) = True And aTiers(p) = intTier - 1 And intTier > 1 Then
-                        'deactivate
-                        Dim selection2 As Selection
-                        selection2 = CATIA.ActiveDocument.Selection
-                        selection2.Clear()
-                        selection2.Add(cRelevantProducts.Item(p))
-                        CATIA.StartCommand("Activate / Deactivate Component")
-                        selection2.Clear()
-                        cDeactivated.Add(cRelevantProducts.Item(p))
-                        bDeactivated(p) = True
-                    End If
-                End If
-            Next p
-
-            'Deactivate last disassembly tier directly
-            For p = 0 To cRelevantProducts.Count - 1
-                If intI = cBaseProducts.Count And aTiers(p) = intTier Then
-                    Dim selektion As Selection
-                    selektion = CATIA.ActiveDocument.Selection
-                    selektion.Clear()
-                    selektion.Add(cRelevantProducts.Item(p))
-                    CATIA.StartCommand("Activate / Deactivate Component")
-                    selektion.Clear()
-                    cDeactivated.Add(cRelevantProducts.Item(p))
-                    bDeactivated(p) = True
-                End If
-            Next p
-
-            'Notify the user if no parts could be disassembled in this tier
-            If intI = intItemp Then
-                Debug.Print("WARNING! No parts could be removed during this cycle." & vbNewLine & "This is usually due to inaccuracies in modelling (e.g. collisions in initial assembly).")
-                For p = 0 To cRelevantProducts.Count - 1
-                    If aTiers(p) = 0 And Not productIsInCollection(cRelevantProducts.Item(p), cBaseProducts) Then
-                        Dim selektion As Selection
-                        selektion = CATIA.ActiveDocument.Selection
-                        selektion.Clear()
-                        selektion.Add(cRelevantProducts.Item(p))
-                        CATIA.StartCommand("Activate / Deactivate Component")
-                        selektion.Clear()
-                        cDeactivated.Add(cRelevantProducts.Item(p))
-                        bDeactivated(p) = True
-                    End If
-                Next p
-                Exit While
-            End If
-
-            'recalculate assembly boundaries and removal distances
-            RecalculateRemovalDistances(cRelevantProducts, bDeactivated)
-
-            intTier += 1
-            int_i = 0
-            int_i_cycle = 0
-
-        End While
-
-        Dim SecondsElapsed As Double
-        Dim MillisecondsElapsed As Double
-        MillisecondsElapsed = (Now - AssemblyTiersStartTime).TotalMilliseconds
-        SecondsElapsed = Math.Round(MillisecondsElapsed / 1000.0, 2)
-        MsgBox("Collision detection algorithm finished execution after " & CStr(SecondsElapsed) & " seconds")
-
-        'Return products to their initial positions, activate them
-        Dim p1 As Integer
-        For p1 = 0 To cRelevantProducts.Count - 1
-            If Not productIsInCollection(cRelevantProducts.Item(p1), cBaseProducts) Then
-                Dim oPosition4 As Object
-                oPosition4 = cRelevantProducts.Item(p1).Position
-                Dim aPos(11)
-                For comp = 0 To 11
-                    aPos(comp) = aInitPos(p1, comp)
-                Next comp
-                oPosition4.SetComponents(aPos)
-                Dim selection4 As Selection
-                selection4 = CATIA.ActiveDocument.Selection
-                selection4.Clear()
-                selection4.Add(cRelevantProducts.Item(p1))
-                CATIA.StartCommand("Activate / Deactivate Component")
-                selection4.Clear()
-            End If
-        Next p1
-
-        'Select a single extraction direction in case there are multiple
-        Dim d2
-        d2 = CreateObject("Scripting.Dictionary")
-        d2.Add("Global X+", 0)
-        d2.Add("Global Y+", 1)
-        d2.Add("Global Z+", 2)
-        d2.Add("Global X-", 3)
-        d2.Add("Global Y-", 4)
-        d2.Add("Global Z-", 5)
-        d2.Add("Local X+", 6)
-        d2.Add("Local Y+", 7)
-        d2.Add("Local Z+", 8)
-        d2.Add("Local X-", 9)
-        d2.Add("Local Y-", 10)
-        d2.Add("Local Z-", 11)
-        'Inverse axis indices
-        Dim d3
-        d3 = CreateObject("Scripting.Dictionary")
-        d3.Add(0, 3)
-        d3.Add(1, 4)
-        d3.Add(2, 5)
-        d3.Add(3, 0)
-        d3.Add(4, 1)
-        d3.Add(5, 2)
-        d3.Add(6, 9)
-        d3.Add(7, 10)
-        d3.Add(8, 11)
-        d3.Add(9, 6)
-        d3.Add(10, 7)
-        d3.Add(11, 8)
-        For int_i = 0 To cRelevantProducts.Count - 1
-            If bChooseExtractionDirection Then
-                Dim sum As Integer
-                sum = 0
-                For intAxis = 0 To intJ - 1
-                    sum = sum + disassDir(int_i, intAxis)
-                Next intAxis
-                'Only for products with multiple extraction directions
-                If sum > 1 Then
-                    'Add options to ComboBox
-                    For intAxis = 0 To intJ - 1
-                        If disassDir(int_i, intAxis) = 1 Then
-                            'ExtractionDirection.ComboBox1.AddItem(d1.Item(intAxis))
-                        End If
-                    Next intAxis
-                    'Highlight the product in CATIA
-                    Dim selection5 As Selection
-                    selection5 = CATIA.ActiveDocument.Selection
-                    selection5.Clear()
-                    selection5.Add(cRelevantProducts.Item(int_i + 1))
-                    'Show dialog
-                    'ExtractionDirection.Show
-                    selection5.Clear()
-                    'Translate chosen axis name back into index 0..11
-                    Dim iChosenDir As Integer
-                    iChosenDir = d2.Item(sChosenDirection)
-                    'Set all other disassembly directions to 0
-                    For intAxis = 0 To intJ - 1
-                        If intAxis = iChosenDir Then
-                            disassDir(int_i, intAxis) = 1
-                        Else
-                            disassDir(int_i, intAxis) = 0
-                        End If
-                    Next intAxis
-                End If
-            End If
-            'Reverse tier values
-            Dim intMaxTier As Integer
-            intMaxTier = intTier - 1
-            If aTiers(int_i) <> 0 Then
-                aTiers(int_i) = intMaxTier + 1 - aTiers(int_i)
-            End If
-            'Reverse disassembly axis (assembly axis = -disass. axis)
-            Dim tempAssemblyDirs As Integer()
-            ReDim tempAssemblyDirs(intJ)
-            For intAxis = 0 To intJ - 1
-                If disassDir(int_i, intAxis) = 1 Then
-                    tempAssemblyDirs(d3.Item(intAxis)) = 1
-                    'disassDir(int_i, intAxis) = 0
-                    'disassDir(int_i, d3.Item(intAxis)) = 1
-                End If
-            Next intAxis
-            For intAxis = 0 To intJ - 1
-                disassDir(int_i, intAxis) = tempAssemblyDirs(intAxis)
-            Next intAxis
-        Next int_i
-
-        'Association of components belonging to sequential tiers
-
-        Dim cClashes1 As Clashes
-        Dim oClash1 As Clash
-        oClash1 = cClashes.Add
-        oClash1.ComputationType = CatClashComputationType.catClashComputationTypeBetweenAll
-        oClash1.InterferenceType = CatClashInterferenceType.catClashInterferenceTypeContact
-        oClash1.Compute()
-        Dim cInitConflicts As Conflicts
-        cInitConflicts = oClash1.Conflicts
-        Dim initConfl As Conflict
-        Dim nConfl As Integer
-        nConfl = 0
-        For Each initConfl In cInitConflicts
-            Dim firstIndex As Integer
-            Dim secondIndex As Integer
-            firstIndex = GetProductIndex(initConfl.FirstProduct, cRelevantProducts)
-            secondIndex = GetProductIndex(initConfl.SecondProduct, cRelevantProducts)
-            If aTiers(firstIndex) = aTiers(secondIndex) - 1 Then
-                precedenceMatrix(firstIndex, secondIndex) = 1
-            End If
-            If aTiers(secondIndex) = aTiers(firstIndex) - 1 Then
-                precedenceMatrix(secondIndex, firstIndex) = 1
-            End If
-        Next initConfl
-
-        'Export data to Excel
-        Dim objExcel As Microsoft.Office.Interop.Excel.Application
-        objExcel = CreateObject("Excel.Application")
-        objExcel.Visible = True
-        objExcel.Workbooks.Add()
-        objExcel.ActiveWorkbook.Sheets.Add.Name = "Precedence Matrix"
-        Dim objSheet1, objSheet2 As Object
-        objSheet1 = objExcel.ActiveWorkbook.Worksheets(2)
-        objSheet1.Name = "Assembly Directions"
-        objSheet2 = objExcel.ActiveWorkbook.Worksheets(1)
-
-        'Assembly directions
-        objSheet1.Cells(1, 1).Value = "Product"
-        objSheet1.Cells(1, 2).Value = "+X"
-        objSheet1.Cells(1, 3).Value = "+Y"
-        objSheet1.Cells(1, 4).Value = "+Z"
-        objSheet1.Cells(1, 5).Value = "-X"
-        objSheet1.Cells(1, 6).Value = "-Y"
-        objSheet1.Cells(1, 7).Value = "-Z"
-        objSheet1.Cells(1, 8).Value = "Assembly Tier"
-        For int_i = 0 To cRelevantProducts.Count - 1
-            objSheet1.Cells(int_i + 2, 1).Value = cRelevantProducts.Item(int_i).Name
-            For intAxis = 0 To intJ - 1
-                objSheet1.Cells(int_i + 2, 2 + intAxis).Value = disassDir(int_i, intAxis)
-            Next intAxis
-            objSheet1.Cells(int_i + 2, intJ + 2).Value = aTiers(int_i)
-        Next int_i
-
-        'Precedence relations
-        For int_i = 0 To cRelevantProducts.Count - 1
-            For int_j = 0 To cRelevantProducts.Count - 1
-                objSheet2.Cells(int_i + 1, int_j + 1).Value = precedenceMatrix(int_i, int_j)
-            Next int_j
-        Next int_i
-
-        'Save and close excel workbook
-        If bConnectivityCheck Then
-            objExcel.ActiveWorkbook.SaveAs(Filename:=xlsPath & xlsFileName & "_AssemblyTiers_CC.xlsx")
-        Else
-            objExcel.ActiveWorkbook.SaveAs(Filename:=xlsPath & xlsFileName & "_AssemblyTiers.xlsx")
-        End If
-        objExcel.ActiveWorkbook.Close(SaveChanges:=True)
-        'close the excel application
-        objExcel.Quit()
-        ReleaseObject(objExcel)
-
-    End Sub
-    Sub ExtractProducts(oCurrentProduct As Product)
-
-        Dim oCurrentTreeNode As Product
-        Dim i As Integer
-
-        For i = 1 To oCurrentProduct.Products.Count
-            oCurrentTreeNode = oCurrentProduct.Products.Item(i)
-
-            'recursive
-            If oCurrentTreeNode.Products.Count > 0 Then
-                ExtractProducts(oCurrentTreeNode)
-            Else
-                Debug.Print(oCurrentTreeNode.PartNumber & " (" & oCurrentTreeNode.Name & ") is a leaf product")
-                'remove special characters from the part number
-                Dim newPartNo As String
-                Dim newCharacter As String
-                newCharacter = " "
-                newPartNo = oCurrentTreeNode.PartNumber
-                newPartNo = Replace(newPartNo, "<", newCharacter)
-                newPartNo = Replace(newPartNo, ">", newCharacter)
-                newPartNo = Replace(newPartNo, "/", newCharacter)
-                oCurrentTreeNode.PartNumber = newPartNo
-                cAllProducts.Add(oCurrentTreeNode)
-            End If
-
-        Next
-
-    End Sub
-
-    Sub GetNextNode(oCurrentProduct As Product)
-
-        Dim oCurrentTreeNode As Product
-        Dim i As Integer
-
-        For i = 1 To oCurrentProduct.Products.Count
-            oCurrentTreeNode = oCurrentProduct.Products.Item(i)
-
-            If IsPart(oCurrentTreeNode) = True Then
-                MsgBox(oCurrentTreeNode.PartNumber & " is a part")
-            ElseIf IsProduct(oCurrentTreeNode) = True Then
-                MsgBox(oCurrentTreeNode.PartNumber & " is a product")
-            Else
-                MsgBox(oCurrentTreeNode.PartNumber & " is a component")
-            End If
-
-            'recursive
-            If oCurrentTreeNode.Products.Count > 0 Then
-                GetNextNode(oCurrentTreeNode)
-            End If
-
-        Next
-
-    End Sub
-
-    Function IsPart(objCurrentProduct As Product) As Boolean
-
-        Dim oTestPart As PartDocument
-
-        oTestPart = Nothing
-
-        On Error Resume Next
-
-        oTestPart = CATIA.Documents.Item(objCurrentProduct.PartNumber & ".CATPart")
-
-        If Not oTestPart Is Nothing Then
-            IsPart = True
-        Else
-            IsPart = False
-        End If
-
-    End Function
-
-    Function IsProduct(objCurrentProduct As Product) As Boolean
-
-        Dim oTestProduct As ProductDocument
-
-        oTestProduct = Nothing
-
-        On Error Resume Next
-
-        oTestProduct = CATIA.Documents.Item(objCurrentProduct.PartNumber & ".CATProduct")
-
-        If Not oTestProduct Is Nothing Then
-            IsProduct = True
-        Else
-            IsProduct = False
-        End If
-
-    End Function
-    Sub Liaison()
-
-        Dim n As Integer = cRelevantProducts.Count
-
-        ReDim liaisonMatrix(n - 1, n - 1)
-
-        'access the clash technology object
-        Dim cClashes As Clashes
-        cClashes = CATIA.ActiveDocument.Product.GetTechnologicalObject("Clashes")
-        'access the groups technology object
-        Dim cGroups As Groups
-        cGroups = CATIA.ActiveDocument.Product.GetTechnologicalObject("Groups")
-
-        'Clash analysis between all products (clash type = contact)
-        Dim int_i, int_j As Integer
-        For int_i = 1 To cRelevantProducts.Count
-            For int_j = 1 To cRelevantProducts.Count
-                If int_j > int_i Then 'only need one half of the combinations
-                    Dim group1 As Group
-                    Dim group2 As Group
-                    group1 = cGroups.Add
-                    group2 = cGroups.Add
-                    group1.AddExplicit(cRelevantProducts.Item(int_i - 1))
-                    group2.AddExplicit(cRelevantProducts.Item(int_j - 1))
-                    'create a new clash analysis
-                    Dim oClash As Clash
-                    oClash = cClashes.Add
-                    oClash.ComputationType = CatClashComputationType.catClashComputationTypeBetweenTwo
-                    oClash.FirstGroup = group1
-                    oClash.SecondGroup = group2
-                    oClash.InterferenceType = CatClashInterferenceType.catClashInterferenceTypeContact
-                    oClash.Compute()
-                    Dim cConflicts As Conflicts
-                    cConflicts = oClash.Conflicts
-                    If cConflicts.Count > 0 Then
-                        'For each contact, write 1 in the spreadsheet
-                        'The matrix is symmetric and 0-diagonal
-                        liaisonMatrix(int_i - 1, int_j - 1) = 1
-                        liaisonMatrix(int_j - 1, int_i - 1) = 1
-                    Else
-                        liaisonMatrix(int_i - 1, int_j - 1) = 0
-                        liaisonMatrix(int_j - 1, int_i - 1) = 0
-                    End If
-                ElseIf int_j = int_i Then
-                    liaisonMatrix(int_i - 1, int_j - 1) = 0
-                End If
-            Next int_j
-        Next int_i
-
-    End Sub
-
-    Function SubassemblyIsConnected(prt As List(Of Integer)) As Boolean
-
-        'List of visited nodes
-        Dim visitedNodes As New List(Of Boolean)
-        Dim prtCount As Integer = prt.Count
-        For x = 0 To prtCount - 1
-            visitedNodes.Add(False)
-        Next
-
-        'Submatrix of liaison adjacency matrix that contains only the nodes of this subassembly
-        Dim liaisonSubmatrix(,) As Integer
-        ReDim liaisonSubmatrix(prtCount, prtCount)
-        For m = 0 To prtCount - 1
-            For k = 0 To prtCount - 1
-                liaisonSubmatrix(m, k) = liaisonMatrix(prt(m), prt(k))
-            Next
-        Next
-
-        'Depth-first search to explore the liaison subgraph from the first node
-        DFS(liaisonSubmatrix, visitedNodes, 0)
-
-        'Check whether all nodes could be visited via liaison connections
-        For i = 0 To prtCount - 1
-            If visitedNodes(i) = False Then
-                Return False
-            End If
-        Next
-
-        Return True
-
-    End Function
-
-    Sub DFS(liaisonSubmatrix(,) As Integer, visitedNodes As List(Of Boolean), v As Integer)
-        'Depth-first search
-
-        If visitedNodes(v) = True Then
-            Exit Sub
-        End If
-
-        visitedNodes(v) = True
-
-        'Neighbors of v
-        Dim neighbors As New List(Of Integer)
-        For i = 0 To visitedNodes.Count - 1
-            If liaisonSubmatrix(v, i) = 1 Then
-                neighbors.Add(i)
-            End If
-        Next
-
-        'Do DFS on all neighbor nodes if they were not visited
-        For Each u In neighbors
-            If visitedNodes(u) = False Then
-                DFS(liaisonSubmatrix, visitedNodes, u)
-            End If
-        Next
-
-    End Sub
-    Function DeactivateFasteners(objProduct As Product)
-
-        Dim objParts As New ArrayList
-        'On the top level of product tree
-        ' objParts = objProduct.Products
-        'Recursive
-        objParts = cAllProducts
-        Dim selection1 As Selection
-        selection1 = CATIA.ActiveDocument.Selection
-        selection1.Clear()
-
-        Dim intFasteners As Integer
-        intFasteners = 0
-
-        For Each prod In objParts
-            Dim sName As String
-            Dim primFastSize As Integer
-
-            sName = LCase(prod.PartNumber)
-            'Debug.Print sName
-            If InStr(sName, "bolt") > 0 Then
-                Debug.Print(prod.Name + " was identified as a bolt")
-                selection1.Add(prod)
-
-                primaryFasteners.Add(prod)
-
-                CATIA.StartCommand("Activate / Deactivate Component")
-                selection1.Clear()
-                intFasteners = intFasteners + 1
-            ElseIf InStr(sName, "screw") > 0 Or InStr(sName, "schraube") > 0 Or (InStr(sName, "iso") > 0 And InStr(sName, "4762") > 0) Or (InStr(sName, "din") > 0 And (InStr(sName, "912") > 0 Or InStr(sName, "933") > 0)) Then
-                Debug.Print(prod.Name + " was identified as a screw")
-                selection1.Add(prod)
-
-                primaryFasteners.Add(prod)
-
-                CATIA.StartCommand("Activate / Deactivate Component")
-                selection1.Clear()
-                intFasteners = intFasteners + 1
-            ElseIf InStr(sName, "clip") > 0 Then
-                Debug.Print(prod.Name + " was identified as a clip")
-                selection1.Add(prod)
-
-                primaryFasteners.Add(prod)
-
-                CATIA.StartCommand("Activate / Deactivate Component")
-                selection1.Clear()
-                intFasteners = intFasteners + 1
-            ElseIf InStr(sName, "wedge") > 0 Then
-                Debug.Print(prod.Name + " was identified as a wedge")
-                selection1.Add(prod)
-
-                primaryFasteners.Add(prod)
-
-                CATIA.StartCommand("Activate / Deactivate Component")
-                selection1.Clear()
-                intFasteners = intFasteners + 1
-                'ElseIf InStr(sName, "pin") > 0 Then
-                '    Debug.Print(prod.Name + " was identified as a pin")
-                '    selection1.Add(prod)
-
-                '    primaryFasteners.Add(prod)
-
-                '    CATIA.StartCommand("Activate / Deactivate Component")
-                '    selection1.Clear()
-                '    intFasteners = intFasteners + 1
-            ElseIf InStr(sName, "nut") > 0 Or (InStr(sName, "iso") > 0 And InStr(sName, "4161") > 0) Or (InStr(sName, "din") > 0 And (InStr(sName, "934") > 0 Or InStr(sName, "439") > 0)) Then
-                Debug.Print(prod.Name + " was identified as a nut")
-                selection1.Add(prod)
-
-                secondaryFasteners.Add(prod)
-
-                CATIA.StartCommand("Activate / Deactivate Component")
-                selection1.Clear()
-                intFasteners = intFasteners + 1
-            ElseIf InStr(sName, "washer") > 0 Or (InStr(sName, "din") > 0 And (InStr(sName, "9021") > 0 Or InStr(sName, "125") > 0 Or InStr(sName, "127") > 0)) Then
-                Debug.Print(prod.Name + " was identified as a washer")
-                selection1.Add(prod)
-
-                secondaryFasteners.Add(prod)
-
-                CATIA.StartCommand("Activate / Deactivate Component")
-                selection1.Clear()
-                intFasteners = intFasteners + 1
-            Else
-                cRelevantProducts.Add(prod)
-            End If
-        Next
-
-        'CATIA.StartCommand ("Activate / Deactivate Component")
-        Debug.Print("Deactivated " + CStr(intFasteners) + " fasteners")
-        intParts = intParts - intFasteners
-        Debug.Print(CStr(intParts) + " parts to assemble")
-        MsgBox("Fasteners are deacivated. Press OK to proceed.")
-
-    End Function
-
-    Function GenerateBoundingBox(partDocument1 As PartDocument, objProduct As Product, i As Integer)
-        'Processes a single part to extract its origin XYZ, min/max X/Y/Z
-
-        CATIA.DisplayFileAlerts = False
-
-        'Declare variables
-        Dim axis
-        Dim remake
-        Dim part1 As Part
-        Dim axisref As Object
-        Dim shapeFactory1 As ShapeFactory
-        Dim hybridShapeFactory1 As HybridShapeFactory
-        Dim sStatus As String
-        Dim hybridShapeD1, hybridShapeD2, hybridShapeD3 As HybridShapeDirection
-        Dim a1, a2, a3, a4, a5, a6 'To change the offsets of the box
-        Dim bodies1 As Bodies
-        Dim body1 As Body
-        Dim reference1 As Reference
-        Dim HybridShapeExtremum1, HybridShapeExtremum2, HybridShapeExtremum3 As HybridShapeExtremum
-        Dim HybridShapeExtremum4, HybridShapeExtremum5, HybridShapeExtremum6 As HybridShapeExtremum
-        Dim originCoord(2)
-        Dim faceSel As Object
-
-        'Check whether we are processing a Part
-        If (InStr(partDocument1.Name, ".CATPart")) <> 0 Then
-            part1 = partDocument1.Part
-            hybridShapeFactory1 = part1.HybridShapeFactory
-
-            Dim axiscoord(2)
-            Dim axissyst
-
-            Dim axisSystem As AxisSystem
-            axisSystem = part1.AxisSystems.Item(1)
-
-            axissyst = axisSystem
-            axisref = axisSystem
-
-            Dim ref_name_systaxis As String
-            ref_name_systaxis = axissyst.Name
-
-            axissyst.IsCurrent = 1
-            axissyst.Name = "BBoxAxis"
-            Dim axname As String
-            axname = axissyst.Name
-
-            'Get Product's Position (rotation and translation)
-            '(for now: relative to the parent product!)
-            Dim PositionArray(11)
-            Dim oPosition As Object
-            oPosition = objProduct.Position
-            oPosition.GetComponents(PositionArray)
-
-            Dim originpoint As HybridShapePointCoord
-            axissyst.GetOrigin(originCoord)
-            'MsgBox "X0 = " & CStr(originCoord(0)) & vbNewLine & "Y0 = " & CStr(originCoord(1)) & vbNewLine & "Z0 = " & CStr(originCoord(2))
-
-            originpoint = hybridShapeFactory1.AddNewPointCoord(originCoord(0), originCoord(1), originCoord(2))
-            axisref = part1.CreateReferenceFromObject(originpoint)
-            axissyst.GetXAxis(axiscoord)
-            hybridShapeD1 = hybridShapeFactory1.AddNewDirectionByCoord(axiscoord(0), axiscoord(1), axiscoord(2))
-            axissyst.GetYAxis(axiscoord)
-            hybridShapeD2 = hybridShapeFactory1.AddNewDirectionByCoord(axiscoord(0), axiscoord(1), axiscoord(2))
-            axissyst.GetZAxis(axiscoord)
-            hybridShapeD3 = hybridShapeFactory1.AddNewDirectionByCoord(axiscoord(0), axiscoord(1), axiscoord(2))
-
-            'hybridShapeD1&2 are not set yet, but used for line creation (from origin of the axis system)
-            Dim Plane_line_1 As HybridShapeLinePtDir
-            Plane_line_1 = hybridShapeFactory1.AddNewLinePtDir(originpoint, hybridShapeD1, 0, 0, False)
-            Dim Plane_line_2 As HybridShapeLinePtDir
-            Plane_line_2 = hybridShapeFactory1.AddNewLinePtDir(originpoint, hybridShapeD2, 0, 0, False)
-
-            Dim oBodies As Bodies
-            oBodies = part1.Bodies
-
-            'J is defined to make unique names for Axis and the Body for the bounding box
-            Dim j As Integer
-            j = oBodies.Count
-
-            'Add new Body "Bounding Box."j to the Bodies of the current Part
-            bodies1 = part1.Bodies
-            body1 = bodies1.Add()
-            body1.Name = "Bounding Box." & j
-
-            Dim hybridBodies1 As HybridBodies
-            hybridBodies1 = body1.HybridBodies
-            Dim hybridBody1 As HybridBody
-            hybridBody1 = hybridBodies1.Add
-            hybridBody1.Name = "definition_points"
-
-
-            'Pick a face of the part to use for HybridShapeExtract
-            faceSel = CATIA.ActiveDocument.Selection
-            faceSel.Clear
-            'The current Part is added to the selection
-            faceSel.Add(part1)
-            'The selection gets rewritten by all the Faces of the selected part ("sel")
-            faceSel.Search("Type=Face,sel")
-
-            Debug.Print("Selected faces: " & CStr(faceSel.Count))
-            intNumFaces += faceSel.Count
-
-            'Need to check whether Extract crashes given this face and try the next one
-            Dim f As Integer
-            For f = 1 To faceSel.Count
-
-                'On Error GoTo ContinueFaceLoop
-
-                reference1 = faceSel.Item(f).Value
-                Debug.Print(TypeName(reference1))
-
-                Dim hybridShapeExtract1 As HybridShapeExtract
-                hybridShapeExtract1 = hybridShapeFactory1.AddNewExtract(reference1)
-                hybridShapeExtract1.PropagationType = 1 'point continuity
-                hybridShapeExtract1.ComplementaryExtract = False
-                hybridShapeExtract1.IsFederated = False
-                reference1 = hybridShapeExtract1
-
-                'Create the 6 Extrenum items for the Solid/Surf.  May not be single points, will be solved with next points
-                HybridShapeExtremum1 = hybridShapeFactory1.AddNewExtremum(reference1, hybridShapeD1, 1)
-                HybridShapeExtremum2 = hybridShapeFactory1.AddNewExtremum(reference1, hybridShapeD1, 0)
-                HybridShapeExtremum3 = hybridShapeFactory1.AddNewExtremum(reference1, hybridShapeD2, 1)
-                HybridShapeExtremum4 = hybridShapeFactory1.AddNewExtremum(reference1, hybridShapeD2, 0)
-                HybridShapeExtremum5 = hybridShapeFactory1.AddNewExtremum(reference1, hybridShapeD3, 1)
-                HybridShapeExtremum6 = hybridShapeFactory1.AddNewExtremum(reference1, hybridShapeD3, 0)
-
-                ' Creates Geometrical Set under the Solid, to contain the construction elements
-
-                Dim hybridBody2 As HybridBody
-                hybridBody2 = hybridBodies1.Item("definition_points")
-
-                hybridBody2.AppendHybridShape(HybridShapeExtremum1)
-                part1.InWorkObject = HybridShapeExtremum1
-                HybridShapeExtremum1.Name = "max_X"
-                hybridBody2.AppendHybridShape(HybridShapeExtremum2)
-                part1.InWorkObject = HybridShapeExtremum2
-                HybridShapeExtremum2.Name = "min_X"
-                hybridBody2.AppendHybridShape(HybridShapeExtremum3)
-                part1.InWorkObject = HybridShapeExtremum3
-                HybridShapeExtremum3.Name = "max_Y"
-                hybridBody2.AppendHybridShape(HybridShapeExtremum4)
-                part1.InWorkObject = HybridShapeExtremum4
-                HybridShapeExtremum4.Name = "min_Y"
-                hybridBody2.AppendHybridShape(HybridShapeExtremum5)
-                part1.InWorkObject = HybridShapeExtremum5
-                HybridShapeExtremum5.Name = "max_Z"
-                hybridBody2.AppendHybridShape(HybridShapeExtremum6)
-                part1.InWorkObject = HybridShapeExtremum6
-                HybridShapeExtremum6.Name = "min_Z"
-
-                part1.UpdateObject(HybridShapeExtremum1)
-                part1.UpdateObject(HybridShapeExtremum2)
-                part1.UpdateObject(HybridShapeExtremum3)
-                part1.UpdateObject(HybridShapeExtremum4)
-                part1.UpdateObject(HybridShapeExtremum5)
-                part1.UpdateObject(HybridShapeExtremum6)
-
-                'part1.Update
-
-                ' Creates a 6 single points using the Extrenums as refs, so if the Extrenum was a line or surf, you can still off planes to these points
-
-                Dim Ref1 As Reference
-                Ref1 = part1.CreateReferenceFromObject(HybridShapeExtremum1)
-                Dim Point1 As HybridShapePointCoord
-                Point1 = hybridShapeFactory1.AddNewPointCoordWithReference(0, 0, 0, Ref1)
-                hybridBody2.AppendHybridShape(Point1)
-                Dim point_ref11 As Reference
-                point_ref11 = part1.CreateReferenceFromObject(Point1)
-
-                Dim Ref2 As Reference
-                Ref2 = part1.CreateReferenceFromObject(HybridShapeExtremum2)
-                Dim Point2 As HybridShapePointCoord
-                Point2 = hybridShapeFactory1.AddNewPointCoordWithReference(0, 0, 0, Ref2)
-                hybridBody2.AppendHybridShape(Point2)
-                Dim point_ref12 As Reference
-                point_ref12 = part1.CreateReferenceFromObject(Point2)
-
-                Dim Ref3 As Reference
-                Ref3 = part1.CreateReferenceFromObject(HybridShapeExtremum3)
-                Dim Point3 As HybridShapePointCoord
-                Point3 = hybridShapeFactory1.AddNewPointCoordWithReference(0, 0, 0, Ref3)
-                hybridBody2.AppendHybridShape(Point3)
-                Dim point_ref13 As Reference
-                point_ref13 = part1.CreateReferenceFromObject(Point3)
-
-                Dim Ref4 As Reference
-                Ref4 = part1.CreateReferenceFromObject(HybridShapeExtremum4)
-                Dim Point4 As HybridShapePointCoord
-                Point4 = hybridShapeFactory1.AddNewPointCoordWithReference(0, 0, 0, Ref4)
-                hybridBody2.AppendHybridShape(Point4)
-                Dim point_ref14 As Reference
-                point_ref14 = part1.CreateReferenceFromObject(Point4)
-
-                Dim Ref5 As Reference
-                Ref5 = part1.CreateReferenceFromObject(HybridShapeExtremum5)
-                Dim Point5 As HybridShapePointCoord
-                Point5 = hybridShapeFactory1.AddNewPointCoordWithReference(0, 0, 0, Ref5)
-                hybridBody2.AppendHybridShape(Point5)
-                Dim point_ref5 As Reference
-                point_ref5 = part1.CreateReferenceFromObject(Point5)
-
-                Dim Ref6 As Reference
-                Ref6 = part1.CreateReferenceFromObject(HybridShapeExtremum6)
-                Dim Point6 As HybridShapePointCoord
-                Point6 = hybridShapeFactory1.AddNewPointCoordWithReference(0, 0, 0, Ref6)
-                hybridBody2.AppendHybridShape(Point6)
-                Dim point_ref6 As Reference
-                point_ref6 = part1.CreateReferenceFromObject(Point6)
-
-                part1.UpdateObject(Point1)
-                part1.UpdateObject(Point2)
-                part1.UpdateObject(Point3)
-                part1.UpdateObject(Point4)
-                part1.UpdateObject(Point5)
-                part1.UpdateObject(Point6)
-
-                'part1.Update
-
-                axissyst.IsCurrent = 1
-
-                'Read extremum coordinates
-                Dim coord(2) As Object
-                Dim absCoord(2) As Object
-
-                Dim TheSPAWorkbench As Workbench
-                TheSPAWorkbench = CATIA.ActiveDocument.GetWorkbench("SPAWorkbench")
-
-                Dim TheMeasurable
-
-                Debug.Print("Global coordinates of local extrema:")
-
-                'Transform local extrema coordinates into global coordinates and update aAssemblyBoundaries
-
-                'Distances to Part Bounding Box faces in local coordinates
-                Dim aBBDistances(5) As Double
-                '8 corner points of the Part Bounding Box (BB) in local coordinates (8x3 array)
-                Dim aBBCornersLocal(7, 2) As Double
-
-                'max_X_loc
-                TheMeasurable = TheSPAWorkbench.GetMeasurable(point_ref11)
-                TheMeasurable.GetPoint(coord)
-                aBBDistances(0) = coord(0)
-                absCoord = {0.0, 0.0, 0.0}
-                Call Coord_Transform(coord, absCoord, objProduct, True)
-                Debug.Print(Point1.Name & " (" & Ref1.DisplayName & "): [" & absCoord(0) & " " & absCoord(1) & " " & absCoord(2) & "]")
-
-                'min_X_loc
-                TheMeasurable = TheSPAWorkbench.GetMeasurable(point_ref12)
-                TheMeasurable.GetPoint(coord)
-                aBBDistances(1) = coord(0)
-                absCoord = {0.0, 0.0, 0.0}
-                Call Coord_Transform(coord, absCoord, objProduct, True)
-                Debug.Print(Point2.Name & " (" & Ref2.DisplayName & "): [" & absCoord(0) & " " & absCoord(1) & " " & absCoord(2) & "]")
-
-                'max_Y_loc
-                TheMeasurable = TheSPAWorkbench.GetMeasurable(point_ref13)
-                TheMeasurable.GetPoint(coord)
-                aBBDistances(2) = coord(1)
-                absCoord = {0.0, 0.0, 0.0}
-                Call Coord_Transform(coord, absCoord, objProduct, True)
-                Debug.Print(Point3.Name & " (" & Ref3.DisplayName & "): [" & absCoord(0) & " " & absCoord(1) & " " & absCoord(2) & "]")
-
-                'min_Y_loc
-                TheMeasurable = TheSPAWorkbench.GetMeasurable(point_ref14)
-                TheMeasurable.GetPoint(coord)
-                aBBDistances(3) = coord(1)
-                absCoord = {0.0, 0.0, 0.0}
-                Call Coord_Transform(coord, absCoord, objProduct, True)
-                Debug.Print(Point4.Name & " (" & Ref4.DisplayName & "): [" & absCoord(0) & " " & absCoord(1) & " " & absCoord(2) & "]")
-
-                'max_Z_loc
-                TheMeasurable = TheSPAWorkbench.GetMeasurable(point_ref5)
-                TheMeasurable.GetPoint(coord)
-                aBBDistances(4) = coord(2)
-                absCoord = {0.0, 0.0, 0.0}
-                Call Coord_Transform(coord, absCoord, objProduct, True)
-                Debug.Print(Point5.Name & " (" & Ref5.DisplayName & "): [" & absCoord(0) & " " & absCoord(1) & " " & absCoord(2) & "]")
-
-                'min_Z_loc
-                TheMeasurable = TheSPAWorkbench.GetMeasurable(point_ref6)
-                TheMeasurable.GetPoint(coord)
-                aBBDistances(5) = coord(2)
-                absCoord = {0.0, 0.0, 0.0}
-                Call Coord_Transform(coord, absCoord, objProduct, True)
-                Debug.Print(Point6.Name & " (" & Ref6.DisplayName & "): [" & absCoord(0) & " " & absCoord(1) & " " & absCoord(2) & "]")
-
-                'Generate 8 corner points (local coordinates) to the aBBCornersLocal
-                Dim m, n, k, c As Integer
-                c = 0
-                For m = 0 To 1
-                    For n = 2 To 3
-                        For k = 4 To 5
-                            aBBCornersLocal(c, 0) = aBBDistances(m)
-                            aBBCornersLocal(c, 1) = aBBDistances(n)
-                            aBBCornersLocal(c, 2) = aBBDistances(k)
-                            'Transform corner point into global coordinates
-                            coord(0) = aBBCornersLocal(c, 0)
-                            coord(1) = aBBCornersLocal(c, 1)
-                            coord(2) = aBBCornersLocal(c, 2)
-                            Call Coord_Transform(coord, absCoord, objProduct, True)
-                            'Record values to aPartBBGlob
-                            Dim CCC(2) As Double    'Corner Coordinates in axis system Congruent to global but in the part's origin
-                            CCC(0) = absCoord(0) - PositionArray(9)
-                            CCC(1) = absCoord(1) - PositionArray(10)
-                            CCC(2) = absCoord(2) - PositionArray(11)
-                            If CCC(0) > aPartBBGlob(i, 0) Then
-                                aPartBBGlob(i, 0) = CCC(0)
-                            End If
-                            If CCC(0) < aPartBBGlob(i, 1) Then
-                                aPartBBGlob(i, 1) = CCC(0)
-                            End If
-                            If CCC(1) > aPartBBGlob(i, 2) Then
-                                aPartBBGlob(i, 2) = CCC(1)
-                            End If
-                            If CCC(1) < aPartBBGlob(i, 3) Then
-                                aPartBBGlob(i, 3) = CCC(1)
-                            End If
-                            If CCC(2) > aPartBBGlob(i, 4) Then
-                                aPartBBGlob(i, 4) = CCC(2)
-                            End If
-                            If CCC(2) < aPartBBGlob(i, 5) Then
-                                aPartBBGlob(i, 5) = CCC(2)
-                            End If
-                            'Update aAssemblyBoundaries (global)
-                            If absCoord(0) > aAssemblyBoundaries(0) Then
-                                aAssemblyBoundaries(0) = absCoord(0)
-                            End If
-                            If absCoord(0) < aAssemblyBoundaries(1) Then
-                                aAssemblyBoundaries(1) = absCoord(0)
-                            End If
-                            If absCoord(1) > aAssemblyBoundaries(2) Then
-                                aAssemblyBoundaries(2) = absCoord(1)
-                            End If
-                            If absCoord(1) < aAssemblyBoundaries(3) Then
-                                aAssemblyBoundaries(3) = absCoord(1)
-                            End If
-                            If absCoord(2) > aAssemblyBoundaries(4) Then
-                                aAssemblyBoundaries(4) = absCoord(2)
-                            End If
-                            If absCoord(2) < aAssemblyBoundaries(5) Then
-                                aAssemblyBoundaries(5) = absCoord(2)
-                            End If
-                            c = c + 1
-                        Next k
-                    Next n
-                Next m
-
-                part1.Update()
-
-                Exit For
-
-                'ContinueFaceLoop:
-
-            Next f
-
-        Else
-            MsgBox("The active document must be a CATPart")
-        End If
-
-    End Function
-
-    Sub RecalculateRemovalDistances(cRelProd As ArrayList, bDeact As Boolean())
-
-        Dim aRemovalDistances(cRelProd.Count - 1, 5)
-        Dim i As Integer
-        Dim relProd As Product
-        'assure that the origin is inside the BB of assembly
-        aAssemblyBoundaries(0) = -1 / 0
-        aAssemblyBoundaries(1) = 1 / 0
-        aAssemblyBoundaries(2) = -1 / 0
-        aAssemblyBoundaries(3) = 1 / 0
-        aAssemblyBoundaries(4) = -1 / 0
-        aAssemblyBoundaries(5) = 1 / 0
-
-        For i = 0 To cRelProd.Count - 1
-            If Not bDeact(i) Then
-                If aInitPos(i, 9) + aPartBBGlob(i, 0) > aAssemblyBoundaries(0) Then
-                    aAssemblyBoundaries(0) = aInitPos(i, 9) + aPartBBGlob(i, 0)
-                End If
-                If aInitPos(i, 9) + aPartBBGlob(i, 1) < aAssemblyBoundaries(1) Then
-                    aAssemblyBoundaries(1) = aInitPos(i, 9) + aPartBBGlob(i, 1)
-                End If
-                If aInitPos(i, 10) + aPartBBGlob(i, 2) > aAssemblyBoundaries(2) Then
-                    aAssemblyBoundaries(2) = aInitPos(i, 10) + aPartBBGlob(i, 2)
-                End If
-                If aInitPos(i, 10) + aPartBBGlob(i, 3) < aAssemblyBoundaries(3) Then
-                    aAssemblyBoundaries(3) = aInitPos(i, 10) + aPartBBGlob(i, 3)
-                End If
-                If aInitPos(i, 11) + aPartBBGlob(i, 4) > aAssemblyBoundaries(4) Then
-                    aAssemblyBoundaries(4) = aInitPos(i, 11) + aPartBBGlob(i, 4)
-                End If
-                If aInitPos(i, 11) + aPartBBGlob(i, 5) < aAssemblyBoundaries(5) Then
-                    aAssemblyBoundaries(5) = aInitPos(i, 11) + aPartBBGlob(i, 5)
-                End If
-            End If
-        Next i
-
-        For i = 0 To cRelProd.Count - 1
-            If Not bDeact(i) Then
-                aRemovalDistances(i, 0) = aAssemblyBoundaries(0) - aPartBBGlob(i, 1)
-                aRemovalDistances(i, 1) = aAssemblyBoundaries(1) - aPartBBGlob(i, 0)
-                aRemovalDistances(i, 2) = aAssemblyBoundaries(2) - aPartBBGlob(i, 3)
-                aRemovalDistances(i, 3) = aAssemblyBoundaries(3) - aPartBBGlob(i, 2)
-                aRemovalDistances(i, 4) = aAssemblyBoundaries(4) - aPartBBGlob(i, 5)
-                aRemovalDistances(i, 5) = aAssemblyBoundaries(5) - aPartBBGlob(i, 4)
-            End If
-        Next i
-
-    End Sub
-
-    'Public Function ArrayLen(a As Object) As Integer
-    '    If IsEmpty(a) Then
-    '        ArrayLen = 0
-    '    Else
-    '        ArrayLen = UBound(a) - LBound(a) + 1
-    '    End If
-    'End Function
-
-    Function Det3x3(dX11 As Double, dX12 As Double, dX13 As Double,
-                dX21 As Double, dX22 As Double, dX23 As Double,
-                dX31 As Double, dX32 As Double, dX33 As Double) As Double
-        '***********************************************
-        '*
-        '* 3x3 matrix determinant calculation (direct)
-        '*
-        '***********************************************
-
-        Det3x3 = dX11 * dX22 * dX33 + dX12 * dX23 * dX31 + dX21 * dX32 * dX13 -
-             dX13 * dX22 * dX31 - dX12 * dX21 * dX33 - dX23 * dX32 * dX11
-    End Function
-    Function Inv3x3(dX11 As Double, dX12 As Double, dX13 As Double,
-           dX21 As Double, dX22 As Double, dX23 As Double,
-           dX31 As Double, dX32 As Double, dX33 As Double, aInv() As Double) As Double()
-        '***********************************************
-        '*
-        '* 3x3 matrix inverse calculation (direct)
-        '*
-        '***********************************************
-        Dim dDet As Double
-
-        ReDim aInv(8)
-
-        dDet = Det3x3(dX11, dX12, dX13, dX21, dX22, dX23, dX31, dX32, dX33)
-        'If dDet = 0 Then Exit Function
-        If dDet = 0 Then Return Nothing
-
-        aInv(0) = (dX22 * dX33 - dX23 * dX32) / Math.Abs(dDet)
-        aInv(1) = (dX13 * dX32 - dX12 * dX33) / Math.Abs(dDet)
-        aInv(2) = (dX12 * dX23 - dX13 * dX22) / Math.Abs(dDet)
-        aInv(3) = (dX23 * dX31 - dX21 * dX33) / Math.Abs(dDet)
-        aInv(4) = (dX11 * dX33 - dX13 * dX31) / Math.Abs(dDet)
-        aInv(5) = (dX13 * dX21 - dX11 * dX23) / Math.Abs(dDet)
-        aInv(6) = (dX21 * dX32 - dX22 * dX31) / Math.Abs(dDet)
-        aInv(7) = (dX12 * dX31 - dX11 * dX32) / Math.Abs(dDet)
-        aInv(8) = (dX11 * dX22 - dX12 * dX21) / Math.Abs(dDet)
-
-        Return aInv
-
-    End Function
-    Sub Coord_Transform(aRel() As Object, aAbs() As Object, oProduct As Product, bRecursively As Boolean)
-
-        Dim vProduct As Object, vCoord(11)
-        Dim oFatherProduct As Product
-        Dim aInv(8) As Double
-
-        'Exit condition, empty object
-        If oProduct Is Nothing Then Exit Sub
-
-        'Redim absolute coords matrix
-        On Error Resume Next
-        'aAbs = {0.0, 0.0, 0.0}
-        On Error GoTo 0
-
-        'Calculate product coordinates
-        vProduct = oProduct
-        vProduct.Position.GetComponents(vCoord)
-
-        'Calculate inverse matrix
-        If IsNothing(Inv3x3(CDbl(vCoord(0)), CDbl(vCoord(1)), CDbl(vCoord(2)),
-                 CDbl(vCoord(3)), CDbl(vCoord(4)), CDbl(vCoord(5)),
-                 CDbl(vCoord(6)), CDbl(vCoord(7)), CDbl(vCoord(8)), aInv)) Then
-            'MsgBox "Error, degenerate transformation", vbOKOnly
-            Exit Sub
-        Else
-            aInv = Inv3x3(CDbl(vCoord(0)), CDbl(vCoord(1)), CDbl(vCoord(2)),
-                 CDbl(vCoord(3)), CDbl(vCoord(4)), CDbl(vCoord(5)),
-                 CDbl(vCoord(6)), CDbl(vCoord(7)), CDbl(vCoord(8)), aInv)
-        End If
-
-        'Calculate transformation
-        aAbs(0) = vCoord(9) + aInv(0) * aRel(0) + aInv(1) * aRel(1) + aInv(2) * aRel(2)
-        aAbs(1) = vCoord(10) + aInv(3) * aRel(0) + aInv(4) * aRel(1) + aInv(5) * aRel(2)
-        aAbs(2) = vCoord(11) + aInv(6) * aRel(0) + aInv(7) * aRel(1) + aInv(8) * aRel(2)
-
-        'If recursive option sepecified, search for parents and applies the transformation again
-        If bRecursively Then
-
-            'Try to assign parent
-            oFatherProduct = Nothing
-            On Error Resume Next
-            oFatherProduct = oProduct.Parent.Parent
-            On Error GoTo 0
-
-            'If OK, recalculate coords
-            If oFatherProduct Is Nothing Then
-            Else
-                If oFatherProduct.PartNumber + ".CATProduct" = CATIA.ActiveDocument.Name Then
-                    aRel(0) = aAbs(0)
-                    aRel(1) = aAbs(1)
-                    aRel(2) = aAbs(2)
-                    Coord_Transform(aRel, aAbs, oFatherProduct, False)
-                Else
-                    aRel(0) = aAbs(0)
-                    aRel(1) = aAbs(1)
-                    aRel(2) = aAbs(2)
-                    Coord_Transform(aRel, aAbs, oFatherProduct, True)
-                End If
-            End If
-
-        End If
-
-    End Sub
-
-    Function productIsInCollection(objProd As Product, prodColl As ArrayList) As Boolean
-        Dim dummyObj As Product
-        productIsInCollection = False
-        For Each dummyObj In prodColl
-            If dummyObj.Name = objProd.Name Then
-                productIsInCollection = True
-                Exit For
-            End If
-        Next
-    End Function
-
-    Sub moveProduct(objProd As Product, intDir As Integer, bPositive As Boolean)
-        Dim intS As Integer
-        If bPositive = True Then
-            intS = intStep
-        Else
-            intS = -intStep
-        End If
-        Dim moveArray(11)
-        moveArray(0) = 1
-        moveArray(1) = 0
-        moveArray(2) = 0
-        moveArray(3) = 0
-        moveArray(4) = 1
-        moveArray(5) = 0
-        moveArray(6) = 0
-        moveArray(7) = 0
-        moveArray(8) = 1
-        moveArray(9) = 0
-        moveArray(10) = 0
-        moveArray(11) = 0
-
-        Dim axisArray(11)
-
-        'movement along global axis
-        If intDir < 6 Then
-            'Attention: for now it is assumed that all products are on the top level of specification tree
-            If intDir = 0 Then
-                moveArray(9) = intS
-            End If
-            If intDir = 1 Then
-                moveArray(10) = intS
-            End If
-            If intDir = 2 Then
-                moveArray(11) = intS
-            End If
-            If intDir = 3 Then
-                moveArray(9) = -intS
-            End If
-            If intDir = 4 Then
-                moveArray(10) = -intS
-            End If
-            If intDir = 5 Then
-                moveArray(11) = -intS
-            End If
-        Else    'movement along local axis
-            Dim oPosition As Object
-            oPosition = objProd.Position
-            oPosition.GetComponents(axisArray)
-            If intDir = 6 Then
-                moveArray(9) = axisArray(0) * intS
-                moveArray(10) = axisArray(1) * intS
-                moveArray(11) = axisArray(2) * intS
-            End If
-            If intDir = 7 Then
-                moveArray(9) = axisArray(3) * intS
-                moveArray(10) = axisArray(4) * intS
-                moveArray(11) = axisArray(5) * intS
-            End If
-            If intDir = 8 Then
-                moveArray(9) = axisArray(6) * intS
-                moveArray(10) = axisArray(7) * intS
-                moveArray(11) = axisArray(8) * intS
-            End If
-            If intDir = 9 Then
-                moveArray(9) = -axisArray(0) * intS
-                moveArray(10) = -axisArray(1) * intS
-                moveArray(11) = -axisArray(2) * intS
-            End If
-            If intDir = 10 Then
-                moveArray(9) = -axisArray(3) * intS
-                moveArray(10) = -axisArray(4) * intS
-                moveArray(11) = -axisArray(5) * intS
-            End If
-            If intDir = 11 Then
-                moveArray(9) = -axisArray(6) * intS
-                moveArray(10) = -axisArray(7) * intS
-                moveArray(11) = -axisArray(8) * intS
-            End If
-        End If
-        Dim prod1nd As Product
-        prod1nd = objProd
-        prod1nd.Move.Apply(moveArray)
-
-    End Sub
-
-    Function collisionDetected(cClashes As Clashes, group1 As Group, group2 As Group) As Boolean
-        'cRelevantProducts As Collection, cDeactivated As Collection
-
-        collisionDetected = False
-
-        'define two groups
-        '    Dim group1 As Group
-        'Dim group2 As Group
-        '     group1 = cGroups.Add
-        ' group2 = cGroups.Add
-        '    group1.AddExplicit product1
-        '    Dim relevantProduct As Product
-        '    For Each relevantProduct In cRelevantProducts
-        '      If Not relevantProduct.Name = product1.Name And Not productIsInCollection(relevantProduct, cDeactivated) Then
-        '        group2.AddExplicit relevantProduct
-        '      End If
-        '    Next relevantProduct
-        'create a new clash analysis
-        Dim oClash As Clash
-        oClash = cClashes.Add
-        oClash.ComputationType = SPATypeLib.CatClashComputationType.catClashComputationTypeBetweenTwo
-        oClash.FirstGroup = group1
-        oClash.SecondGroup = group2
-        oClash.InterferenceType = SPATypeLib.CatClashInterferenceType.catClashInterferenceTypeClearance
-        'oClash.Clearance = dCollSens
-        oClash.Compute()
-        Dim cConflicts As Conflicts
-        cConflicts = oClash.Conflicts
-        If cConflicts.Count > 0 Then
-            'MsgBox "Detected a collision: " & product1.Name
-            'If at least one conflict value exceeds the collision sensitivity, it is a collision
-            Dim oConflict As Conflict
-            Dim c As Integer
-            For c = 1 To cConflicts.Count
-                oConflict = cConflicts.Item(c)
-                oConflict.Status = SPATypeLib.CatConflictStatus.catConflictStatusRelevant
-                If oConflict.Type = SPATypeLib.CatConflictType.catConflictTypeClash Then
-                    If oConflict.Value < -dCollSens Then
-                        collisionDetected = True
-                        'Debug.Print("Clash detected: " & oConflict.FirstProduct.Name & " - " & oConflict.SecondProduct.Name & " = " & oConflict.Value)
-                        Exit For
-                    End If
-                End If
-            Next c
-        End If
-    End Function
-
-    Function productReachedFinalPosition(objProd As Product, i1 As Integer) As Boolean
-        productReachedFinalPosition = False
-        Dim posArray(11)
-        Dim oPosition As Object
-        oPosition = objProd.Position
-        oPosition.GetComponents(posArray)
-        If posArray(9) > aRemovalDistances(i1, 0) Then
-            productReachedFinalPosition = True
-            'MsgBox "X+ removal distance reached by " & objProd.Name
-        End If
-        If posArray(9) < aRemovalDistances(i1, 1) Then
-            productReachedFinalPosition = True
-            'MsgBox "X- removal distance reached by " & objProd.Name
-        End If
-        If posArray(10) > aRemovalDistances(i1, 2) Then
-            productReachedFinalPosition = True
-            'MsgBox "Y+ removal distance reached by " & objProd.Name
-        End If
-        If posArray(10) < aRemovalDistances(i1, 3) Then
-            productReachedFinalPosition = True
-            'MsgBox "Y- removal distance reached by " & objProd.Name
-        End If
-        If posArray(11) > aRemovalDistances(i1, 4) Then
-            productReachedFinalPosition = True
-            'MsgBox "Z+ removal distance reached by " & objProd.Name
-        End If
-        If posArray(11) < aRemovalDistances(i1, 5) Then
-            productReachedFinalPosition = True
-            'MsgBox "Z- removal distance reached by " & objProd.Name
-        End If
-    End Function
-
-    Function productHasValidDisassDir(i1 As Integer, disassDir(,) As Object) As Boolean
-        productHasValidDisassDir = False
-        Dim j As Integer
-        For j = 0 To 11
-            If disassDir(i1, j) = 1 Then
-                productHasValidDisassDir = True
-                Exit For
-            End If
-        Next j
-    End Function
-
-    Function Tree(s1, q)
-
-        For Each s2 In s1.Products
-            Tree(s2, q)
-        Next
-
-        Dim parentAssy As Object
-        parentAssy = s1.Parent.Parent
-
-        If StrComp(TypeName(parentAssy), "Product") = 0 Then
-            parentAssy.ReferenceProduct.Products.Item(s1.Name).Name = CStr(s1.PartNumber) & CStr("." & q)
-            q = q + 1
-        End If
-
-    End Function
-
-    Private Sub RenameSingleLevel(ByRef oCurrentProd As Product)
-
-        On Error Resume Next
-
-        'More declarations
-        Dim ItemToRename As Product
-        Dim ToRenamePartNumber As String
-        Dim lNumberOfItems As Long
-        Dim RenameArray(2000) As String
-        Dim i As Integer
-        Dim j As Integer
-        Dim k As Integer
-
-        oCurrentProd = oCurrentProd.ReferenceProduct    'You have to work with the "ReferenceProduct" object
-        lNumberOfItems = oCurrentProd.Products.Count
-
-        'For i = 1 To lNumberOfItems                         'Clear out the rename array
-        '    RenameArray(i) = ""                             'Don't know if this is necessary
-        'Next
-
-        'Run through this loop once, to set everything to a dummy name, to avoid naming conflicts
-        For i = 1 To lNumberOfItems                             'Cycle through the assembly's children
-            ItemToRename = oCurrentProd.Products.Item(i)    'Declare which item we are working on
-
-            ToRenamePartNumber = ItemToRename.PartNumber        'Get the Part Number
-            'ToRenamePartNumber = ItemToRename.DescriptionRef   'Toggle these two lines for testing
-
-            RenameArray(i) = ToRenamePartNumber                 'Building the list of part names for the numbering loop
-
-            k = 0                                               'Numbering Loop
-            For j = 1 To i                                      'This loop checks and sets the instance number
-                If RenameArray(j) = ToRenamePartNumber Then
-                    k = k + 1
-                End If
-            Next
-            CATIA.StatusBar = ItemToRename.Name & " > " & ToRenamePartNumber & "." & k
-            'MsgBox ItemToRename.Name & " / " & ToRenamePartNumber & "." & k    'This line is for testing only
-            ItemToRename.Name = ToRenamePartNumber & "TEMP." & k    'Set the new instance name, to a TEMP dummy value
-
-        Next
-
-        'Run through this loop to set the name finally, then the recursion call
-        For i = 1 To lNumberOfItems
-            ItemToRename = oCurrentProd.Products.Item(i)
-
-            ToRenamePartNumber = ItemToRename.PartNumber        'Toggle these two lines for testing
-            'ToRenamePartNumber = ItemToRename.DescriptionRef   'Toggle these two lines for testing
-
-            RenameArray(i) = ToRenamePartNumber
-
-            k = 0
-            For j = 1 To i
-                If RenameArray(j) = ToRenamePartNumber Then
-                    k = k + 1
-                End If
-            Next
-
-            CATIA.StatusBar = ItemToRename.Name & " > " & ToRenamePartNumber & "." & k
-            'MsgBox ItemToRename.Name & " / " & ToRenamePartNumber & "." & k    'For testing
-
-            ItemToRename.Name = ToRenamePartNumber & "." & k    'Set the new instance name final
-
-            If ItemToRename.Products.Count <> 0 Then        'Recursive Call for version 0.1.2
-                If oList.exists(ItemToRename.PartNumber) Then GoTo Finish
-                If ItemToRename.PartNumber = ItemToRename.ReferenceProduct.Parent.Product.PartNumber Then oList.Add(ItemToRename.PartNumber, 1)
-                Call RenameSingleLevel(ItemToRename)
-            End If
-
-Finish:
-        Next
-
-    End Sub
-
-    Function GetProductIndex(objProd As Product, cProds As ArrayList) As Integer
-        Dim produkt As Product
-        Dim intAns As Integer
-        intAns = 0
-        For Each produkt In cProds
-            If produkt.Name = objProd.Name Then
-                GetProductIndex = intAns
-                Exit Function
-            End If
-            intAns = intAns + 1
-        Next produkt
-        Return intAns
-    End Function
-
-    Function BoundingBoxesOverlap(int_i As Integer, iStaticProduct As Integer) As Boolean
-        If aPartBBGlob(int_i, 1) >= aPartBBGlob(iStaticProduct, 0) Or aPartBBGlob(int_i, 0) <= aPartBBGlob(iStaticProduct, 1) Then
-            If aPartBBGlob(int_i, 3) >= aPartBBGlob(iStaticProduct, 2) Or aPartBBGlob(int_i, 2) <= aPartBBGlob(iStaticProduct, 3) Then
-                If aPartBBGlob(int_i, 5) >= aPartBBGlob(iStaticProduct, 4) Or aPartBBGlob(int_i, 4) <= aPartBBGlob(iStaticProduct, 5) Then
-                    Return False
-                End If
-            End If
-        End If
-        Return True
-    End Function
-
-    Sub ExportBBVolumes()
-        'Use Excel
-        Dim objExcel As Microsoft.Office.Interop.Excel.Application
-        objExcel = CreateObject("Excel.Application")
-        objExcel.Visible = True
-        objExcel.Workbooks.Add()
-        objExcel.ActiveWorkbook.Sheets.Add.Name = "BB Volumes"
-        Dim objSheet1 As Object
-        objSheet1 = objExcel.ActiveWorkbook.Worksheets(1)
-        'Write data
-        objSheet1.Cells(1, 1).Value = "Product"
-        objSheet1.Cells(1, 2).Value = "BB volume"
-        For int_i = 0 To cRelevantProducts.Count - 1
-            Dim dPartBBVolume As Double
-            dPartBBVolume = (aPartBBGlob(int_i, 0) - aPartBBGlob(int_i, 1)) * (aPartBBGlob(int_i, 2) - aPartBBGlob(int_i, 3)) * (aPartBBGlob(int_i, 4) - aPartBBGlob(int_i, 5))
-            objSheet1.Cells(int_i + 2, 1).Value = cRelevantProducts.Item(int_i).Name
-            objSheet1.Cells(int_i + 2, 2).Value = dPartBBVolume
-        Next int_i
-        'Save and close excel workbook
-        objExcel.ActiveWorkbook.SaveAs(Filename:=xlsPath & xlsFileName & "_BB Volumes.xlsx")
-        objExcel.ActiveWorkbook.Close(SaveChanges:=True)
-        'close the excel application
-        objExcel.Quit()
-        ReleaseObject(objExcel)
-    End Sub
-
-    Private Sub ReleaseObject(ByVal obj As Object)
-        Try
-            Dim intRel As Integer = 0
-            Do
-                intRel = System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
-            Loop While intRel > 0
-            'MsgBox("Final Released obj # " & intRel)
-        Catch ex As Exception
-            MsgBox("Error releasing object" & ex.ToString)
-            obj = Nothing
-        Finally
-            GC.Collect()
-        End Try
-    End Sub
-
-    Sub ShowForm()
-        'Create a new form to input algorithm specifications first
-        'Dim Form2 As Form = New Form()
-        Me.Text = "Algorithm specifications"
-        Me.Size = New System.Drawing.Size(350, 400)
-        'Create elements for parameter inputs
-        'Code variant for BB calculation
-        'Dim BBCodeComboBox As ComboBox = New ComboBox()
-        BBCodeComboBox.Items.Add(1)
-        BBCodeComboBox.Items.Add(2)
-        BBCodeComboBox.Location = New System.Drawing.Point(200, 20)
-        BBCodeComboBox.Size = New System.Drawing.Size(50, 20)
-        BBCodeComboBox.DropDownStyle = ComboBoxStyle.DropDownList
-        Dim Label1 As System.Windows.Forms.Label = New System.Windows.Forms.Label()
-        Label1.Text = "Bounding Box code type"
-        Label1.Location = New System.Drawing.Point(20, 20)
-        Label1.Size = New System.Drawing.Size(150, 20)
-        'Projection check
-        'Dim BBPCCheckBox As System.Windows.Forms.CheckBox = New System.Windows.Forms.CheckBox()
-        BBPCCheckBox.Location = New System.Drawing.Point(200, 50)
-        Dim Label2 As System.Windows.Forms.Label = New System.Windows.Forms.Label()
-        Label2.Text = "BB projection check"
-        Label2.Location = New System.Drawing.Point(20, 50)
-        Label2.Size = New System.Drawing.Size(150, 20)
-        'Connectivity check
-        'Dim CCCheckBox As System.Windows.Forms.CheckBox = New System.Windows.Forms.CheckBox()
-        CCCheckBox.Location = New System.Drawing.Point(200, 80)
-        Dim Label3 As System.Windows.Forms.Label = New System.Windows.Forms.Label()
-        Label3.Text = "Connectivity check"
-        Label3.Location = New System.Drawing.Point(20, 80)
-        Label3.Size = New System.Drawing.Size(150, 20)
-        'Automatic step
-        'Dim AutoStepCheckBox As System.Windows.Forms.CheckBox = New System.Windows.Forms.CheckBox()
-        AutoStepCheckBox.Location = New System.Drawing.Point(200, 110)
-        Dim Label4 As System.Windows.Forms.Label = New System.Windows.Forms.Label()
-        Label4.Text = "Automatic step"
-        Label4.Location = New System.Drawing.Point(20, 110)
-        Label4.Size = New System.Drawing.Size(150, 20)
-        'Step
-        'Dim StepTextBox As System.Windows.Forms.TextBox = New System.Windows.Forms.TextBox()
-        StepTextBox.Text = 5
-        StepTextBox.Location = New System.Drawing.Point(200, 140)
-        StepTextBox.Size = New System.Drawing.Size(50, 20)
-        Dim Label5 As System.Windows.Forms.Label = New System.Windows.Forms.Label()
-        Label5.Text = "Step [mm]"
-        Label5.Location = New System.Drawing.Point(20, 140)
-        Label5.Size = New System.Drawing.Size(150, 20)
-        'Collision sensitivity
-        'Dim CollSensTextBox As System.Windows.Forms.TextBox = New System.Windows.Forms.TextBox()
-        CollSensTextBox.Text = 2
-        CollSensTextBox.Location = New System.Drawing.Point(200, 170)
-        CollSensTextBox.Size = New System.Drawing.Size(50, 20)
-        Dim Label6 As System.Windows.Forms.Label = New System.Windows.Forms.Label()
-        Label6.Text = "Collision sensitivity [mm]"
-        Label6.Location = New System.Drawing.Point(20, 170)
-        Label6.Size = New System.Drawing.Size(150, 20)
-        'Choice of extraction direction
-        'Dim ExtractDirCheckBox As System.Windows.Forms.CheckBox = New System.Windows.Forms.CheckBox()
-        ExtractDirCheckBox.Location = New System.Drawing.Point(200, 200)
-        Dim Label7 As System.Windows.Forms.Label = New System.Windows.Forms.Label()
-        Label7.Text = "Choice of disassembly axis"
-        Label7.Location = New System.Drawing.Point(20, 200)
-        Label7.Size = New System.Drawing.Size(150, 20)
-        'Number of disassembly axis
-        'Dim AxisComboBox As ComboBox = New ComboBox()
-        AxisComboBox.Items.Add(6)
-        AxisComboBox.Items.Add(12)
-        AxisComboBox.Location = New System.Drawing.Point(200, 230)
-        AxisComboBox.Size = New System.Drawing.Size(50, 20)
-        AxisComboBox.DropDownStyle = ComboBoxStyle.DropDownList
-        Dim Label8 As System.Windows.Forms.Label = New System.Windows.Forms.Label()
-        Label8.Text = "Number of disassembly axis"
-        Label8.Location = New System.Drawing.Point(20, 230)
-        Label8.Size = New System.Drawing.Size(150, 20)
-        'Desired name of the output Excel file
-        'Dim XLSTextBox As System.Windows.Forms.TextBox = New System.Windows.Forms.TextBox()
-        XLSTextBox.Text = "Product"
-        XLSTextBox.Location = New System.Drawing.Point(200, 260)
-        Dim Label9 As System.Windows.Forms.Label = New System.Windows.Forms.Label()
-        Label9.Text = "Excel file name"
-        Label9.Location = New System.Drawing.Point(20, 260)
-        Label9.Size = New System.Drawing.Size(150, 20)
-        'OK button
-        'Dim OKButton As System.Windows.Forms.Button = New System.Windows.Forms.Button()
-        OKButton.Text = "Accept parameters"
-        OKButton.Location = New System.Drawing.Point(100, 310)
-        OKButton.Size = New System.Drawing.Size(150, 40)
-
-        'Add control elements to the form
-        Me.Controls.Add(Label1)
-        Me.Controls.Add(Label2)
-        Me.Controls.Add(Label3)
-        Me.Controls.Add(Label4)
-        Me.Controls.Add(Label5)
-        Me.Controls.Add(Label6)
-        Me.Controls.Add(Label7)
-        Me.Controls.Add(Label8)
-        Me.Controls.Add(Label9)
-        Me.Controls.Add(BBCodeComboBox)
-        Me.Controls.Add(BBPCCheckBox)
-        Me.Controls.Add(CCCheckBox)
-        Me.Controls.Add(AutoStepCheckBox)
-        Me.Controls.Add(StepTextBox)
-        Me.Controls.Add(CollSensTextBox)
-        Me.Controls.Add(ExtractDirCheckBox)
-        Me.Controls.Add(AxisComboBox)
-        Me.Controls.Add(XLSTextBox)
-        Me.Controls.Add(OKButton)
-
-        Me.ShowDialog()
-    End Sub
-
-    Private Sub OKButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OKButton.Click
-        iBoundingBoxCode = BBCodeComboBox.SelectedItem
-        bBoundingBoxProjectionCheck = BBPCCheckBox.Checked
-        bConnectivityCheck = CCCheckBox.Checked
-        bAutomaticStep = AutoStepCheckBox.Checked
-        dCollSens = CDbl(CollSensTextBox.Text)
-        bChooseExtractionDirection = ExtractDirCheckBox.Checked
-        intJ = AxisComboBox.SelectedItem
-        xlsFileName = XLSTextBox.Text
-        Debug.Print("Parameters accepted")
-        Me.Hide()
-        Me.CatMain()
-    End Sub
-
-End Class
-
-
diff --git a/CatiaNetTest/bin/Debug/CatiaNetTest.exe b/CatiaNetTest/bin/Debug/CatiaNetTest.exe
index d2d81280ebb16fa2c7d50cca9758469d25641910..8960b70385807dec3ae8cc117c32c9a58f193aee 100644
Binary files a/CatiaNetTest/bin/Debug/CatiaNetTest.exe and b/CatiaNetTest/bin/Debug/CatiaNetTest.exe differ
diff --git a/CatiaNetTest/bin/Debug/CatiaNetTest.pdb b/CatiaNetTest/bin/Debug/CatiaNetTest.pdb
index a65f3f03da0a546f7d8d37c4588e18a22d6f8ae0..d2456861c3bc060ca06f25fb35dd93f773a41c9e 100644
Binary files a/CatiaNetTest/bin/Debug/CatiaNetTest.pdb and b/CatiaNetTest/bin/Debug/CatiaNetTest.pdb differ
diff --git a/CatiaNetTest/obj/Debug/CatiaNetTest.exe b/CatiaNetTest/obj/Debug/CatiaNetTest.exe
index d2d81280ebb16fa2c7d50cca9758469d25641910..8960b70385807dec3ae8cc117c32c9a58f193aee 100644
Binary files a/CatiaNetTest/obj/Debug/CatiaNetTest.exe and b/CatiaNetTest/obj/Debug/CatiaNetTest.exe differ
diff --git a/CatiaNetTest/obj/Debug/CatiaNetTest.pdb b/CatiaNetTest/obj/Debug/CatiaNetTest.pdb
index a65f3f03da0a546f7d8d37c4588e18a22d6f8ae0..d2456861c3bc060ca06f25fb35dd93f773a41c9e 100644
Binary files a/CatiaNetTest/obj/Debug/CatiaNetTest.pdb and b/CatiaNetTest/obj/Debug/CatiaNetTest.pdb differ