private ICodeSource Construct(XUnitTypeName unit)
        {
            if (!_resolver.TryGetValue(unit.GetTypename(), out var type1))
            {
                throw new NotImplementedException();
            }


            ValueOfSomeTypeExpression[] sources;

            var constr = type1.GetConstructors()
                         .Where(a =>
            {
                var pa = a.GetParameters();
                foreach (var info in pa)
                {
                    if (!info.ParameterType.Implements <IUnit>())
                    {
                        return(false);
                    }
                }
                return(true);
            })
                         .OrderByDescending(a => a.GetParameters().Length)
                         .ToArray();
            var typesDict = TypeFinder.Make(_sink);

            if (constr.Length == 0)
            {
                sources = typesDict.GetTypeSources(type1);
                if (sources.Any())
                {
                    var src = sources[0];
                    return(new ExpressionCodeSource(src.Expression,
                                                    src.Root == ValueOfSomeTypeExpressionRoot.Left));
                }

                return(null);
            }

            var ccc = constr[0];


            var list = typesDict.FindParameters(ccc, t => Construct(new XUnitTypeName(t.Name)), out var hasLeft);

            // var hasLeft = list.Any(q => q.Root == ValueOfSomeTypeExpressionRoot.Left);
            if (!hasLeft)
            {
                sources = typesDict.GetTypeSources(type1);
                if (sources.Any())
                {
                    var src = sources[0];
                    return(new ExpressionCodeSource(src.Expression,
                                                    src.Root == ValueOfSomeTypeExpressionRoot.Left));
                }

                throw new NotImplementedException();
            }

            return(MethodCallCodeSource.MakeFromConstructor(unit, list, true));
        }
        private void TryCreateInternal()
        {
            if (_args.Input.Is <PlanarDensity, Length, LinearDensity>("*"))
            {
                Debug.Write("");
            }

            var cc = _args.Input;
            var lu = cc.LeftMethodArgumentName + ".Unit";
            var ru = cc.RightMethodArgumentName + ".Unit";

            Scan(ValueOfSomeTypeExpressionRoot.Left, cc.Left.Unit, Kind2.Property, ExpressionPath.FromSplit(lu));
            Scan(ValueOfSomeTypeExpressionRoot.Right, cc.Right.Unit, Kind2.Property, ExpressionPath.FromSplit(ru));

            _conversionMethodScanner = ConversionMethodScanner.Scan(_resolver.Assembly);

            var reductor = new ExpressionsReductor(n =>
            {
                string varName = null;
                if (n == lu || n == ru)
                {
                    varName = n.Replace(".", "");
                }
                return(AddVariable(n, varName));
            });

            var convertType = Construct(cc.Right.Unit);

            if (convertType.Code == ru)
            {
                convertType = null;
            }
            else
            {
                reductor.AddAny(convertType);
            }
            // convertType.AddToDeleteMe(reductor);

            ICodeSource result = Construct(cc.Result.Unit);

            Func <string> addExtraValueMultiplication = null;

            ICodeSource G1()
            {
                if (!_resolver.TryGetValue(cc.Result.Unit.TypeName, out var type1))
                {
                    throw new NotImplementedException();
                }
                if (_conversionMethodScanner.Dictionary.TryGetValue(type1, out var list))
                {
                    var typesDict = TypeFinder.Make(_sink);
                    foreach (var i in list)
                    {
                        var aaa = typesDict.FindParameters(i, null, out var hl);
                        return(MethodCallCodeSource.Make(i, aaa, hl));
                    }
                }

                return(null);
            }

            if (result is null)
            {
                result = G1();
                if (result != null)
                {
                    addExtraValueMultiplication = () => { return(result.Code + "." + nameof(IUnitDefinition.Multiplication)); };
                }
            }

            if (result is null)
            {
            }
            reductor.AddAny(result);
            //result.AddToDeleteMe(reductor);
            reductor.ReduceExpressions();
            if (addExtraValueMultiplication != null)
            {
                reductor.ForceReduce(new ExpressionPath(result));
            }


            // =============================
            if (result?.Code == "specificHeatCapacity.Unit.DenominatorUnit")
            {
                Debug.WriteLine("");
            }
            switch (convertType)
            {
            case null:
                break;

            case MethodCallCodeSource _:
                _args.Result.ConvertRight(AddVariable(convertType.Code, "targetRightUnit"));
                break;

            default:
                _args.Result.ConvertRight(convertType.Code);
                break;
            }

            if (result is MethodCallCodeSource)
            {
                _args.Result.ResultUnit = AddVariable(result.Code, "resultUnit");
            }
            else
            {
                _args.Result.ResultUnit = result.Code;
            }
            if (addExtraValueMultiplication != null)
            {
                _args.Result.ResultMultiplication = addExtraValueMultiplication();
            }
        }