Upgrade Options

    The Upgrade Options tab is the third step in setting up a migration project with the VBUC, after selecting the projects to migrate and resolving the references. This step is very important since this defines how the VBUC will generate the .NET code.

    The following screenshot shows the main elements of the Upgrade Options tab:


    This is a description of these elements:

    1. The upgrade options are divided in sub sections, where each section refers to different types of components or categories of options supported by the VBUC:

    • DataAccess: This section determines the way in which the Data Access components will be migrated. There are options for ADODB, DAO and RDO.
    • Grids: Since grid components are usually the most complex third party components in a VB6 application, the VBUC has a section with options for the most commonly used ones.
    • Microsoft: This section has options on how to migrate the components that came built in with Visual Basic 6.0; these are widely used in most VB6 applications.
    • Others: With the time Mobilize has added support for other controls that are widely used by VB6 developers. These are defined in this section.
    • Sheridan: The controls created by this company (now called Infragistics) were widely used when VB6 was very popular. That’s why the VBUC has support for these controls, and this section defines how these controls are migrated.
    • CodeConversion: This is probably the most important section in the upgrade options, and defines different alternatives for the overall code migration, as opposed to the previous sections, that defined how to migrate specific controls.

    2. For each one of the upgrade options the VBUC provides a link with “details” for that option. This explains in detail what each of the options will do and also provides a snippet of code in each one of the languages (VB6, C# and VB.NET), showing how the original application would look like and how that code would be migrated if that option is selected.

    3. Each of the upgrade options has a set of alternatives that can be selected and that will define the behavior of the VBUC for that particular option. This dropdown will select this behavior.

    Upgrade Options Choices

    This is a detailed description of each one of the upgrade options and the different upgrade choices for them, with suggestions on when to use one or the other.

    About COM Interop

    In general, for every option that has to do with a third party component, there will be a choice to migrate it using COM Interop. The use of this option is also the default for components that are not supported by the VBUC.

    The use of COM Interop is recommended if you require a fast migration and are not markedly worried about future maintainability of the application or performance issues.

    COM Interop will usually have some performance drawbacks, and there are components that simply won’t work through COM Interop in .NET, so this is something that needs to be researched before executing the migration for any component that you plan on using through this method.

    About Helper classes

    To reduce the amount of manual work involved in the migration of the VB6 code to .NET, Mobilize has created a set of helper classes in .NET.

    The helper classes provide .NET versions of functions that were available in VB6 or provide .NET wrappers for other .NET components exposing interfaces similar to those in the VB6 controls they will replace. For example, the RecordSetHelper class wraps the .NET DataSet class and provides a set of properties and methods available in the RecordSet class in VB6 thus allowing a more direct migration of the VB6 code to .NET.

    For each one of these helper classes, Mobilize provides the source code in .NET as part of the migrated application, therefore the client can modify these in any way they want once the migration process has been completed.


    The options in this section define how the data access components will be migrated.


    • ADO.NET using System.Data.Common and helper classes

      This is the recommended option, since the upgrade of the data access technologies improves the performance of the data access significantly. Also, the use of helper classes greatly reduces the amount of manual work required to achieve functional equivalence. This option also supports any kind of database engine.

      One thing to consider though is that if you migrate the data access to ADO.NET and there are components that were bound to ADODB, these components will probably not work through COM Interop and you will have to migrate them with an equivalent .NET control.

    • ADO.NET using SqlClient

      This option is recommended if the VB6 code uses exclusively SQL Server as the database engine, and the user does not want to use Mobilize’s helper classes (these helper classes are provided with the source code and are delivered as part of the migrated code, so that Mobilize will not hold any copyrights on them).

      This option usually requires a bit of additional manual work because of differences in both platforms. For example, the RecordSet class doesn’t exist in .NET and the equivalent class is the DataSet, which doesn’t have methods like MoveNext and MoveFirst, the helper classes address these differences, but when using SqlClient this is not the case, and these changes must be performed manually.

    • COM Interop

      When planning on using ADODB through COM Interop it is important to know that most .NET components’ data binding won’t work with the data source being a COM component.


    • DAO to ADO.NET with helpers based on System.Data.Commons

      This is equivalent to the option described above for ADODB.

    • COM Interop

      This is equivalent to the option described above for ADODB.


    The options to migrate RDO are equivalent to the options to migrate ADODB, please refer to the previous section for details.

    • COM Interop

    • ADO.NET using SqlClient

    • ADO.NET using System.Data.Common and helpers classes


    These are the options for the grid controls supported by the VBUC out of the box. This list includes the most common controls used by VB6 applications.

    It is worth remembering that the VBUC is a fully customizable tool, therefore if an application uses a grid control not present in this list, it is possible for Mobilize to create a customization to migrate it automatically to a .NET component. It’s also important for the options that use components that are not part of the .NET Framework


    • COM Interop

    • FarPoint Spread Helper

      This option migrates the COM version of the FarPoint grid control to .NET using a helper class created by Mobilize. This helper class is based on the .NET version of the control (FarPoint Spread for Windows Forms), and it is used to provide properties and methods that are similar to the VB6 version of the control.

      For example, the VB6 version of the grid has a Row and Col properties that specify the current cell that will be used for operations (such as setting a style or value). The .NET version of the grid doesn’t have those properties and whenever a value or style is set for a particular cell you must specify the column and row to apply it. The idea of the helper class is to remove the need for those changes and keep track of the current column and row internally.


    • COM Interop

    • Microsoft MSDataGridLib to Component1’s C1.Win.C1TrueDBGrid

      With this option selected the VBUC will replace the MSDataGridLib.DataGrid control with ComponentOne’s C1TrueDBGrid.

      The mappings performed by the VBUC take into account the most common properties and methods of the DataGrid control, therefore some manual effort might be required to achieve functional equivalence.


    • COM Interop

    • Component1’s C1FlexGrid

      This option will replace the MSFlexGridLib.MSFlexGrid control with ComponentOne’s C1FlexGrid control.

      The mappings of these controls include the most commonly used classes, properties and methods in the MSFlexGridLib library, therefore some manual work will be required to achieve full functional equivalence in the migrated application.

    • Mobilize Helper

      This option migrates the MSFlexGrid class with a .NET component created by Mobilize that extends the System.Windows.Forms.DataGridView control.


    • COM Interop

    • ComponentOneTrueDBGrid (.Net version)

      With this option the classes in the TrueDBGridControl library will be replaced by the VBUC with equivalent classes in the C1.Win.C1TrueDBGrid namespace.

    • .NET component that extends the DataGridView

      This option will replace the TrueDBGrid COM component with a helper class based on the System.Windows.Forms.DataGridView control in .NET.


    • COM Interop

    • Component1’s C1FlexGrid

      This option will replace the VSFlexControl.VSFlexGrid control with ComponentOne’s C1FlexGrid control.

      The mappings of these controls include the most commonly used classes, properties and methods in the MSFlexGridLib library, therefore some manual work will be required to achieve full functional equivalence in the migrated application.


    This section includes options to migrate the common controls created by Microsoft and shipped with Visual Basic 6.0.

    All these options have two choices: to migrate using COM Interop and to migrate using .NET native components. In general it is recommended to use the .NET native components, although in some cases there might be some manual changes required to achieve functional equivalence.


    • COM Interop

    • Microsoft Calendar control (MSACAL) to .NET native components

      The calendar control is replaced with the System.Windows.Forms.MonthCalendar control in the migrated application.


    • COM Interop

    • MsComCtl2 to Native .NET component (System.Windows.Forms)

      The controls in the MSComCtl2 library related to dates are migrated to .NET equivalent controls, i.e:

      • DTPicker control is migrated to System.Windows.Forms.DateTimePicker
      • MonthView control is migrated to System.Windows.Forms.MonthCalendar


    • COM Interop

    • MsComctLib to Native .NET component (System.Windows.Forms)

      The controls in component are widely used in VB6 applications and all of them have alternatives in .NET, although some of them have somewhat different behavior, requiring some manual work to verify the functional equivalence. The following table shows the mappings for these controls:

      Class Maps To
      MSComctlLibStatusBar System.Windows.Forms.StatusStrip
      MSComctlLibToolbar System.Windows.Forms.ToolStrip
      MSComctlLibImageList System.Windows.Forms.ImageList
      MSComctlLibTabStrip System.Windows.Forms.TabControl
      MSComctlLibTreeView System.Windows.Forms.TreeView
      MSComctlLibImageCombo System.Windows.Forms.ComboBox
      MSComctlLibListView System.Windows.Forms.ListView
      MSComctLib.ProgressBar System.Windows.Forms.ProgressBar


    • COM Interop

    • MsComDlg to Native .NET component (System.Windows.Forms)

      In VB6 the Common Dialog control was used for multiple purposes (about box, color picker dialog, font selection dialog, help dialog, open file dialog, printer dialog, save file dialog). The .NET Framework provides different controls for each one of these, all of them in the System.Windows.Forms namespace.

      The VBUC migrates automatically the Common Dialog instances to the appropriate control in .NET, and in some rare scenarios there are some manual changes required to achieve functional equivalence.


    • COM Interop

    • MsMask to Native .NET component (System.Windows.Forms)

      With this option selected the MSMask.MaskedBox control is automatically migrated to the System.Windows.Forms.MaskedTextBox control.

      Some manual work is required since there are some differences in things like the format of the mask property in this control.


    • COM Interop

    • Microsoft’s MSWLess to System.Windows.Forms

      This options makes the VBUC replace the Microsoft Windowless controls with standard .NET controls in the System.Windows.Forms namespace.


    • COM Interop

    • Microsoft’s MSXML2 library to System.Xml .NET

      Selecting this option makes the VBUC migrate the classes in the MSXML2 library to the equivalent elements in the System.Xml namespace in .NET.

      Most of the things in this library don’t require manual changes, however things like DOMParseError require some manual work.


    • COM Interop

    • RichTextBox to System.Windows.Forms

      With this option selected the VBUC will migrate the RichTextBox control to the equivalent .NET control System.Windows.Forms.RichTextBox


    • COM Interop

    • Microsoft Internet Controls to .Net Native

      In VB6 the controls in the SHDocVw library are used to load Web pages inside a VB6 application.

      In .NET the System.Windows.Forms.WebBrowser control is used with this objective, and even though is used with the same purpose, the behavior is slightly different and some manual changes are required to achieve functional equivalence.


    This section provides different options to migrate other controls that are common in VB6 applications and that don’t fit in any of the other sections.

    As with the previous options, all these components have two alternatives when migrating them to .NET, one is the migration using COM Interop and the second one is to use .NET components.


    • COM Interop

    • System.EnterpriseServices

      With this option the VBUC upgrades COM+ components to classes using the System.EnterpriseServices namespace.

      This option performs most of the needed changes to get a COM+ object purely in .NET, however there might be some manual changes to be performed in order to achieve full functional equivalence.


    • COM Interop

    • SteemaTeeChart Pro Activex Control v5 to SteemaTeeChart for .Net v4

      With this option the ActiveX TeeChart component is replaced by the .NET version of the same component. Since the interfaces of both versions are very similar there is usually little manual work to be performed by the developers after the migration is executed.


    • COM Interop

    • Xarray to System.Array class

      This option allows the automatic migration of the XArrayObject.XARRAY object into a .NET Array class.

      There are a few considerations to be taken into account when using this option since arrays behave differently in .NET and the lower bound is always 0 whereas you can define the bound in VB6; this might cause some issues in the migrated application and must be reviewed by the developers in the generated code.


    • COM Interop

    • XArrayDB Helper

      This option tells the VBUC to upgrade the XArrayDB class to a helper class written by Mobilize based on a System.Data.DataTable class.

      This option is recommended when the XArrayDB class is used only to store data in a two-dimensional structure. If the class is being used as a data source for other controls (such as a TrueDBGrid) some manual work will be required to achieve the same behavior as in the original application.


    Sheridan controls (now Infragistics) were a set of components widely used in VB6 that provided some functionality not present in the built-in VB6 controls. Since these controls are so widely used Mobilize has added support for the most common of them.

    The mappings created by Mobilize for these controls change some of them to equivalent third-party components in .NET or standard .NET controls. As usual, there’s also the possibility to continue using the ActiveX controls through COM Interop.


    • COM Interop

    • Sheridan’s SSActiveTreeView to System.Windows.Forms.TreeView

      This option makes the VBUC migrate the Sheridan’s TreeView control to the standard .NET TreeView control (part of the System.Windows.Forms namespace).


    • COM Interop

    • System.Windows.Forms

      With this option selected the VBUC will replace the controls in the SSCalendarWidgets library with the DateTimePicker and MonthCalendar controls in the .NET framework.


    • COM Interop

    • InfragisticsUltraSuite (.Net version)

      The InfragisticsUltraSuite is the .NET version of the controls in the SSDataWidgets library (Sheridan became Infragistics in the year 2000). With this option the VBUC upgrades the ActiveX version of these controls to the .NET counterparts.

    • Component ONE (.Net version)

      This option replaces the Sheridan controls in this library with similar components created by Component One (the C1.Win.C1TrueDBGrid namespace). The supported controls are the SSDBDropDown and the SSDBGrid.

      It is recommended to use these mappings if the client already has the license for the Component One controls and don’t want to buy the Infragistics one or if they are using more controls from this library (besides the grid and drop down).


    • COM Interop

    • Sheridan’s SSDesignerWidgets to System.Windows.Forms.TabControl

      Select this option to replace the CTabs control with the System.Windows.Forms.TabControl in .NET.


    • COM Interop

    • Sheridan’s SSListbar members to Infragistics’ UltraWinListBar

      With this option the elements in the stBar library are replaced with classes in the Infragistics.Win.UltraWinListBar, which are the new version of the same control written for .NET by Infragistics.


    • COM Interop

    • SSRibbon to Native

      The SSRibbon control is a button that can have two states (pressed or not pressed). If this option is selected the VBUC migrates the ribbon control to a .NET checkbox or radio button according to the original behavior in the VB6 application.


    • COM Interop

    • Sheridan’s SSSplitter class members to System.Windows.Forms.SplitContainer

      This option tells the VBUC to replace the SSSplitter control from Sheridan with the SplitContainer and SplitterPanel controls in .NET.


    • COM Interop

    • Sheridan’s ActiveThreed controls to System.Windows.Forms

      With this option the VBUC will replace controls in the Threed library from Sheridan with standard .NET components that provide similar functionality to the original controls.

      It is important to note that some of the classes might not have mapping yet, therefore it will be necessary for the developers executing the migration to verify this before the migration since this might add additional manual work.

    Code Conversion

    The options in this section don’t depend upon the projects having specific controls or components (as did the previous sections). These options are more related to the way the code is generated in some scenarios.


    • .NET Assemblies with COM Visible

      This option should be used when the migrated application needs to be used from another ActiveX component (such as an existing C++ application or a VB6 application that won’t be migrated at the same time).

      The option tells the VBUC to generate the necessary attributes for classes and for the project so the legacy applications are able to see the signatures of the migrated application.

      It is important to note that when an application is migrated it is possible that some of the signatures, especially in cases where complex objects were passed as parameters to methods and functions. In such cases a manual work is required to overcome these issues.

    • Out Process and Application Domains using Helpers Classes

      This option is used to generate .NET code that emulates the behavior of ActiveX EXEs and ActiveX DLLs that use instantiation types different to the default.

      Mobilize has created a set of helper classes to achieve the same behavior as the original application and it also generates the code in a way that allows this behavior by using ComponentClassServer and Application Domains.

    • - Standard .Net Assemblies

      This is the default option and should be used in most of the cases, basically converts VB6 DLLs and EXEs into .NET assemblies with equivalent functionality.

      If the original VB6 application relies in the instantiation model (MultiUse, GlobalMultiUse, etc) this won’t be supported when converting to .NET and alternative solutions must be evaluated and implemented manually.

    Default Property Resolution

    Default properties are a feature of VB6 that allows the developer to access a property of an object in an implicit way. E.g, you can assign a TextBox to a string variable, and VB6 will assume that you are assigning the value of the Text property (which is the default property).

    Since this is not supported in .NET, the name of the property must be invoked explicitly in the migrated code.

    • Static code analysis and helper classes

      With this option the VBUC will try to figure out the type of every variable with a default property, and if the type cannot be found, the migrated code will have a call to the ReflectionHelper library, that will find the default property at runtime and return the correct value.

      This option is recommended if you want to sped up the process of manual changes and if the type of the variable with the default property being accessed cannot be known at runtime.

    • Static code analysis only

      With this option the VBUC will try to figure out the type of every variable with a default property, and if the type cannot be found, the migrated code will havetry to cast the object to the target type, and a EWI will be generated indicating that the variable is forced to another type.

    Error Handling

    • Leave On Error Statements (VB.NET Only)

      This option is available only when the target of the migration is VB.NET.

      The idea of this option is to keep the same error handling mechanisms that were present in the original application, thus reducing the amount of manual work to achieve functional equivalence.

      The only issue with this approach is that the use of On Error statements (especially On Error Resume Next) is seen as a legacy strategy, and the recommendation is to use the try catch structures introduced with .NET.

    • Convert To Try-Catch

      This is the default option and the VBUC tries to replace all the On Error blocks with try catch blocks.

      There are two considerations when selecting this option:

      The first one is that the use of try catch blocks doesn’t provide a behavior equivalent to the On Error Resume Next in VB6. When migrating these blocks the VBUC will create a single try catch block that will prevent errors from breaking the application but might change the behavior of it since the flow of execution will be stopped at the first error. Some manual work will have to be performed in these cases to ensure the functional equivalence.

      The second consideration is that since the structure of both error handling statements is different, there are cases where an on error statement cannot be converted to try catch, e.g, if there’s a loop that has a on error goto statement inside and the label being pointed is outside that loop, the VBUC will not be able to generate an equivalent try catch block. In VB.NET this will still work since the on error statements will remain, however it won’t in C# and some manual changes will be needed.

    • To Try-Catch With Lambdas (C# Only)

      This option works the same way as the simple convert to try-catch when converting on error goto statements, the difference shows up when migrating on error resume next statements.

      The generated code uses lambda expressions (which means that it is available only for C# and for .NET Framework 3.5 or later) to achieve similar behavior as the on error resume next.

      Basically the on error resume next is equivalent to add a try catch block around each statement in code segment that it affects, however that would look really bad and would be very hard to maintain. Mobilize has overcome this by creating a helper class that receives an array of lambda expressions (one for each statement inside the original on error resume next block) and internally executes all the statements inside a try catch block.

      This alternative reduces the amount of manual work when migrating the application without making it harder to maintain.

    Form Constructors

    In .NET, every form in an application has two files by default, one contains the information about the visual elements (such as position and default values) and the other one contains the logic associated (methods and event handlers).

    This option allows the user to select where the constructor of the form will be located (it won’t affect the behavior of the application and it’s just a matter of style).

    • Form constructors in the Designer file (Designer.cs or Designer.vb)

      This will generate the constructor of the form inside the designer file of the form.

    • Form constructors in the Logic file (.cs or .vb)

      This will generate the constructor of the form inside the logic file of the form. This might be recommended if the Load event is not migrated to the default Load event in .NET because it will make the code more readable, although in the end it doesn’t change the behavior of the application.

    Form Load

    The Load event of the forms behaves in a different way in .NET and VB6, and the correct way to migrate it will depend upon the way the VB6 application is written.

    In VB6 the form load event can be called directly and executed before the form is displayed, this is not possible in .NET.

    • FormLoad mechanism upgraded using a helper

      This option generates helper methods to wrap load and unload events, and keeps track of the current status of the window to achieve functional equivalence, this option also keeps track of every control in the form and disposes them when the form is manually unloaded.

      This option is recommended when load and unload events are used in the original application.

      Using this option might increase the effort of maintaining the application once functional equivalence has been achieved. It also adds some additional control mechanisms that might make the code a bit harder to read.

    • FormLoad event upgraded as a method invoked from form constructor

      This alternative converts the Load event handler to a simple method that will be called from the constructor of the form, this prevents issues that can happen when the logic requires the load event to be called before the form is displayed, however there might be issues when the logic in the constructor assumes that all the components in the form are available, which is not the case in .NET before the form is displayed.

    • FormLoad event upgraded to .NET native event

      With this option the Form Load event will be migrated to the .NET native Load event, which means that the logic in this event handler will be executed when the form is displayed.

      There might be some issues with this approach if in the original application the load event was called before the form is displayed, because code after that call will assume certain state of the form but that code will not be executed in .NET, if that is not the case this is the preferred option.

    Free COM Objects

    • Free COM Objects memory using helper

      A common problem after migrating applications to .NET that use COM components through Interop is the generation of memory leaks because the objects are not disposed correctly and the .NET garbage collection mechanism doesn’t remove them from memory on time.

      With this option, every time an instance of an object used through COM Interop is created in the migrated application it’s done through a helper class created by Mobilize. The idea of the helper class is to keep track of all the COM objects and when the context in which they were created is closed (a method exits or a form is closed) the objects are manually removed from memory.

      This option is only useful if the migrated application will continue using components through COM Interop.

    • Free COM Objects memory manually

      If the application doesn’t use COM Interop components or if they are rarely used this option can be used to avoid the generation of additional unnecessary code.

    Generate Project as Stubs

    • Stubs Generation For Projects

      With this option the VBUC will generate all the projects of the application as empty projects (all methods, classes and forms will be there but there won’t be any content in the methods (they will be stubs).

      This option is very useful to start migrating large applications with several projects, the idea is to make the application compile faster and then begin the migration of individual projects and incorporate the migrated code into the stub methods.

    • None

      This will migrate the entire application with no stubs generated for the original elements of the application.

    Late Binding Resolution

    • Static code analysis and helper classes

      With this option, if the VBUC isn’t able to determine the type of an object and a method or property is being accessed in that object, the generated code will have calls to Mobilize’s helper classes that will use reflection to invoke that member in the object.

      This has the advantage of compiling without any manual changes, however it might have some performance problems because Reflection is used.

    • Static code analysis only

      With this option, when the VBUC is unable to determine the type of an object and a method or call is invoked on that object, the VBUC will generate the call (even when the object will not have a type defined and the call won’t compile) along with a EWI that will indicate the developer that the type of the object must be defined before being able to compile the application.

      This option will require additional manual work and there might be scenarios where it might not be possible to determine the type of the element before runtime, but if it is possible the quality of the code will be better since it will be early bound.

    Line and Shape

    • Helper class

      With this option the Line and Shape classes from the original application will be migrated to helper classes created by Mobilize.

      These helper classes are 100% written in .NET and the source code will be provided, making this the preferred alternative.

    • PowerPack and Helper class

      Microsoft created a set of classes distributed as a Power Pack to help migrating VB6 code to .NET, this option will migrate the line class to a class called LineShape in the power pack libraries.

      This approach removes the manual work required for the line class, however the use of the power pack libraries is discouraged by Microsoft for new applications and it was marked as deprecated since the framework 3.5 was released.

    Mid Left Right Strings

    • Native String class functions

      With this option the VBUC converts functions such as the Mid, Left and Right defined in the vba.String library of VB6 to standard .NET string functions (string.Left, string.IndexOf, string.Right, string.Mid, etc).

      This works well in most of the cases, however there might be some issues with certain scenarios with fixed length strings.

    • Support function in Microsoft.VisualBasic.Compatibility.VB6.Support namespace

      This option uses the string manipulation functions defined in the classes provided by Visual Basic power packs to replace the same functions present in the original application.

      This option reduces the amount of manual work but implies the use of deprecated elements which are defined in the Compatibility namespace.

    Stubs Generation

    • Upgrade Stubs generation for non-upgraded elements

      The idea of this option is that when an element (property or method) is not supported by the VBUC in an element that is partially supported, the VBUC will create a stub method that will be called whenever the original member was called in VB6. With these stubs, the developer performing manual changes will be able to find an alternative in .NET for that particular member and make the fix in a single location (inside the stub method) instead of going to every usage.

    • Upgrade Note indicating not updated element during upgrade process

      With this option the VBUC will generate calls to the unsupported members (even though this might generate code that doesn’t compile) and a EWI comment indicating that this call must be reviewed. This keeps the code looking like the original application but might add additional manual work since the fixes will have to be applied everywhere that component is used in the application.


    • Microsoft.VisualBasic.Collection support class

      This will use the Microsoft.VisualBasic.Collection compatibility class to migrate the Collection class to .NET.

      This will remove the manual work for this element, however this means using a legacy class.

    • System.Collections.Specialized.OrderedDictionary Native .NET class

      This will replace the Collection class from VB6 with the OrderedDictionary class in .NET. In general the strategy works with no manual changes, although the migrated code might be a bit harder to understand since the OrderedDictionary has a mandatory key parameter which wasn’t the case of the Collection class in VB6, to overcome this the VBUC generates a GUID for the key when it was not present in the original application.

    Download VBUC Free Trial
    Download VBUC Now

    It's time to eradicate VB6
    ROI of eradicating VB6

    8 Proven Tips for
    Planning a Successful Migration

    8 Tips for migration