/// <summary>
        /// create conversion code
        /// </summary>
        /// <param name="sourceType"></param>
        /// <param name="sourceCode"></param>
        /// <param name="targetType"></param>
        /// <returns>conversion code converting sourceCode to the targetType</returns>
        public static CodeExpression GetConversionCode(RaisDataType sourceType, CodeExpression sourceCode, RaisDataType targetType, CodeStatementCollection supprtStatements)
        {
            CodeExpression codeRet;

            if (sourceType.IsSameType(targetType))
            {
                return(sourceCode);
            }
            if (targetType.IsLibType || sourceType.IsLibType)
            {
                if (MathNode.GetTypeConversion != null)
                {
                    return(MathNode.GetTypeConversion(targetType.Type, sourceCode, sourceType.Type, supprtStatements));
                }
                return(CastOrConvert(sourceCode, sourceType.Type, targetType.Type, supprtStatements));
            }
            string srcType = sourceType.DevType.TypeString;
            string tgtType = targetType.DevType.TypeString;

            if (srcType.StartsWith(tgtType))
            {
                return(sourceCode);
            }
            if (tgtType.StartsWith(srcType))
            {
                return(new CodeCastExpression(tgtType, VPLUtil.GetCoreExpressionFromCast(sourceCode)));
            }
            TypeConverter converter = TypeDescriptor.GetConverter(targetType.Type);

            if (converter.CanConvertFrom(sourceType.Type))
            {
                MathNode.AddImportLocation(typeof(TypeConverter).Assembly.Location);
                string converterName = "conv" + targetType.Type.Name;
                if (!MathNodeVariable.VariableDeclared(supprtStatements, converterName))
                {
                    CodeVariableDeclarationStatement cs1 = new CodeVariableDeclarationStatement(
                        typeof(TypeConverter), converterName,
                        new CodeMethodInvokeExpression(
                            new CodeTypeReferenceExpression(typeof(TypeDescriptor)), "GetConverter",
                            new CodeExpression[] { new CodeSnippetExpression("typeof(" + tgtType + ")") }));
                    supprtStatements.Add(cs1);
                }
                //=================================================
                //
                codeRet = new CodeCastExpression(tgtType,
                                                 new CodeMethodInvokeExpression(
                                                     new CodeVariableReferenceExpression(converterName), "ConvertFrom",
                                                     new CodeExpression[] { sourceCode }));
                MathNode.Trace("\tcode 102: source type:{0}, target type:{1} result=converter.ConvertFrom(code);", sourceType, targetType);
            }
            else
            {
                codeRet = CastOrConvert(sourceCode, sourceType.Type, targetType.Type, supprtStatements);
            }
            return(codeRet);
        }
        public bool LoadData(ITestData test)
        {
            try
            {
                _testData = (TestData)test;
                //provide drawing attributes for parameters
                mroot = new MathNodeRoot();
                if (_testData.Parameters.Count > 2)
                {
                    mroot.ChildNodeCount = _testData.Parameters.Count;
                }
                parameters.Properties.Clear();
                for (int i = 0; i < _testData.Parameters.Count; i++)
                {
                    mroot[i] = (MathNode)_testData.Parameters[i].CloneExp(mroot);
                    parameters.Properties.Add(new PropertySpec(_testData.Parameters[i].VariableName + ":" + _testData.Parameters[i].CodeVariableName, _testData.Parameters[i].VariableType.Type));
                }
                foreach (IPropertyPointer pp in _testData.Pointers)
                {
                    parameters.Properties.Add(new PropertySpec(pp.ToString() + ":" + pp.CodeName, pp.ObjectType));                    //.PointerDataType));
                }
                //
                CodeGeneratorOptions o = new CodeGeneratorOptions();
                o.BlankLinesBetweenMembers = false;
                o.BracingStyle             = "C";
                o.ElseOnClosing            = false;
                o.IndentString             = "    ";
                //
                CSharpCodeProvider cs = new CSharpCodeProvider();
                StringWriter       sw;
                sw = new StringWriter();
                cs.GenerateCodeFromCompileUnit(_testData.CU, sw, o);
                //
                string sCode = sw.ToString();
                sw.Close();
                //
                int pos = sCode.IndexOf("a tool.");
                if (pos > 0)
                {
                    sCode = sCode.Substring(0, pos) + "Limnor Visual Object Builder." + sCode.Substring(pos + 7);
                }
                //
                textBox1.Text = sCode;
                //
                CompilerParameters cp = new CompilerParameters();
                foreach (AssemblyRef ar in _testData.Assemblies)
                {
                    MathNode.AddImportLocation(ar.Location);
                }
                foreach (string s in MathNode.ImportLocations)
                {
                    cp.ReferencedAssemblies.Add(s);
                }
                cp.GenerateExecutable = false;
                CompilerResults crs = cs.CompileAssemblyFromDom(cp, new CodeCompileUnit[] { _testData.CU });
                if (crs.Errors.HasErrors)
                {
                    MathNode.Trace("Error compiling.");
                    MathNode.IndentIncrement();
                    FormCompilerError dlg = new FormCompilerError();
                    for (int i = 0; i < crs.Errors.Count; i++)
                    {
                        MathNode.Trace(crs.Errors[i].ToString());
                        dlg.AddItem(crs.Errors[i]);
                    }
                    MathNode.IndentDecrement();
                    dlg.TopLevel = false;
                    dlg.Parent   = this;
                    dlg.Show();
                    dlg.TopMost = true;
                    dlg.BringToFront();
                }
                else
                {
                    Type[] types = crs.CompiledAssembly.GetExportedTypes();
                    if (types != null)
                    {
                        for (int i = 0; i < types.Length; i++)
                        {
                            if (types[i].Name == _testData.ClassName)
                            {
                                _mi = types[i].GetMethod(_testData.MethodName);
                                if (_mi != null)
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
                textBox2.Text = MathNode.GetLogContents();
                return(true);
            }
            catch (Exception err)
            {
                MathNode.Log(this, err);
                textBox2.Text = MathNode.GetLogContents();
            }

            return(false);
        }
        /// <summary>
        /// knowing the code is of different type, make conversion code
        /// </summary>
        /// <param name="sourceValue"></param>
        /// <param name="targetType"></param>
        /// <param name="csc"></param>
        /// <returns></returns>
        static CodeExpression CodeExpConvertTo(CodeExpression sourceCode, Type sourceType, Type targetType, CodeStatementCollection supprtStatements)
        {
            if (targetType.Equals(typeof(void)))
            {
                if (sourceCode == null)
                {
                    MathNode.Trace("code 00: target type is void. Input code is null. Return null for code.");
                }
                else
                {
                    MathNode.Trace("code 00: target type is void. Input code becomes a statement (0). Return null for code.", sourceCode.ToString());
                    supprtStatements.Add(new CodeExpressionStatement(sourceCode));
                }
                return(null);
            }
            CodeExpression codeRet;
            TypeConverter  converter = TypeDescriptor.GetConverter(targetType);

            if (converter.CanConvertFrom(sourceType))
            {
                MathNode.AddImportLocation(typeof(TypeConverter).Assembly.Location);
                string converterName = "conv" + targetType.Name;
                if (!MathNodeVariable.VariableDeclared(supprtStatements, converterName))
                {
                    CodeVariableDeclarationStatement cs1 = new CodeVariableDeclarationStatement(
                        typeof(TypeConverter), converterName,
                        new CodeMethodInvokeExpression(
                            new CodeTypeReferenceExpression(typeof(TypeDescriptor)), "GetConverter",
                            new CodeExpression[] { new CodeSnippetExpression("typeof(" + targetType.FullName + ")") }));
                    supprtStatements.Add(cs1);
                }
                //=================================================
                codeRet = new CodeCastExpression(targetType,
                                                 new CodeMethodInvokeExpression(
                                                     new CodeVariableReferenceExpression(converterName), "ConvertFrom",
                                                     new CodeExpression[] { sourceCode }));
                MathNode.Trace("code 2: source type:{0}, target type:{1} result=converter.ConvertFrom(code);", sourceType, targetType);
            }
            else
            {
                if (sourceCode is CodePrimitiveExpression)
                {
                    CodePrimitiveExpression codep = sourceCode as CodePrimitiveExpression;
                    if (targetType.Equals(typeof(string)))
                    {
                        if (codep.Value == null)
                        {
                            codeRet = new CodeCastExpression(targetType, sourceCode);
                            MathNode.Trace("code 3: source type:{0}, target type:{1} result=null;", sourceType, targetType);
                        }
                        else
                        {
                            if (codep.Value is string)
                            {
                                codeRet = sourceCode;
                                //
                                MathNode.Trace("code 4: source type:{0}, target type:{1} result=code;", sourceType, targetType);
                            }
                            else
                            {
                                codeRet = new CodeMethodInvokeExpression(sourceCode, "ToString", new CodeExpression[] { });
                                MathNode.Trace("code 5: source type:{0}, target type:{1} result=code.ToString();", sourceType, targetType);
                            }
                        }
                    }
                    else                     //none-string primative
                    {
                        codeRet = new CodeCastExpression(targetType, sourceCode);
                        MathNode.Trace("code 6: source type:{0}, target type:{1}, result=({1})code;", sourceType, targetType);
                    }
                }
                else
                {
                    if (sourceType.Equals(typeof(void)))
                    {
                        codeRet = null;
                        if (sourceCode == null)
                        {
                            MathNode.Trace("code 7a: source type:{0}, target type:{1} code is null;", sourceType, targetType);
                        }
                        else
                        {
                            supprtStatements.Add(new CodeExpressionStatement(sourceCode));
                            MathNode.Trace("code 7: source type:{0}, target type: {1}. code used as a statement; return null as CodeExpression.", sourceType, targetType);
                        }
                    }
                    else if (targetType.Equals(typeof(string)))
                    {
                        codeRet = new CodeMethodInvokeExpression(sourceCode, "ToString", new CodeExpression[] { });
                        MathNode.Trace("code 8: source type:{0}, target type:{1} result=code.ToString();", sourceType, targetType);
                    }
                    else
                    {
                        //check to see if casting can be done
                        codeRet = new CodeCastExpression(targetType, sourceCode);
                        MathNode.Trace("code 9: source type:{0}, target type:{1}. cast it: result=({1})code;", sourceType, targetType);
                    }
                }
            }
            return(codeRet);
        }