refactor: reformat

refactor: reformat

--- src/Reni/Type/ArrayType.cs
+++ src/Reni/Type/ArrayType.cs
@@ -9,344 +9,348 @@
 using Reni.SyntaxTree;
 using Reni.TokenClasses;

-namespace Reni.Type
+namespace Reni.Type;
+
+sealed class ArrayType
+    : TypeBase
+        , ISymbolProviderForPointer<DumpPrintToken>
+        , ISymbolProviderForPointer<ConcatArrays>
+        , ISymbolProviderForPointer<TextItem>
+        , ISymbolProviderForPointer<ToNumberOfBase>
+        , ISymbolProviderForPointer<Mutable>
+        , ISymbolProviderForPointer<ArrayReference>
+        , ISymbolProviderForPointer<Count>
+        , IForcedConversionProviderForPointer<ArrayReferenceType>
+        , IRepeaterType
+        , IChild<TypeBase>
 {
-    sealed class ArrayType
-        : TypeBase
-            , ISymbolProviderForPointer<DumpPrintToken>
-            , ISymbolProviderForPointer<ConcatArrays>
-            , ISymbolProviderForPointer<TextItem>
-            , ISymbolProviderForPointer<ToNumberOfBase>
-            , ISymbolProviderForPointer<Mutable>
-            , ISymbolProviderForPointer<ArrayReference>
-            , ISymbolProviderForPointer<Count>
-            , IForcedConversionProviderForPointer<ArrayReferenceType>
-            , IRepeaterType
-            , IChild<TypeBase>
-    {
-        [Node]
-        [SmartNode]
-        readonly ValueCache<RepeaterAccessType> RepeaterAccessTypeCache;
-        [Node]
-        [SmartNode]
-        readonly ValueCache<NumberType> NumberCache;
-
-        internal sealed class Options : DumpableObject
+    internal sealed class Options : DumpableObject
+    {
+        internal static readonly string DefaultOptionsId = Create().Data.Id;
+
+        public Flag IsMutable { get; }
+        public Flag IsTextItem { get; }
+        Flags Data { get; }
+
+        Options(string optionsId)
         {
-            Flags Data { get; }
-
-            Options(string optionsId)
-            {
-                Data = new Flags(optionsId);
-                IsMutable = Data.Register("mutable");
-                IsTextItem = Data.Register("text_item");
-                Data.Align();
-                Data.IsValid.Assert();
-            }
-
-            public Flag IsMutable { get; }
-            public Flag IsTextItem { get; }
-
-            public static Options Create(string optionsId = null) => new Options(optionsId);
-            internal static readonly string DefaultOptionsId = Create().Data.Id;
-
-            protected override string GetNodeDump() => DumpPrintText;
-            public string DumpPrintText => Data.DumpPrintText;
+            Data = new(optionsId);
+            IsMutable = Data.Register("mutable");
+            IsTextItem = Data.Register("text_item");
+            Data.Align();
+            Data.IsValid.Assert();
         }

-        public ArrayType(TypeBase elementType, int count, string optionsId)
+        protected override string GetNodeDump() => DumpPrintText;
+        public string DumpPrintText => Data.DumpPrintText;
+
+        public static Options Create(string optionsId = null) => new(optionsId);
+    }
+
+    [DisableDump]
+    internal TypeBase ElementType { get; }
+
+    internal int Count { get; }
+
+    [Node]
+    [SmartNode]
+    readonly ValueCache<RepeaterAccessType> RepeaterAccessTypeCache;
+
+    [Node]
+    [SmartNode]
+    readonly ValueCache<NumberType> NumberCache;
+
+    Options OptionsValue { get; }
+
+    public ArrayType(TypeBase elementType, int count, string optionsId)
+    {
+        ElementType = elementType;
+        Count = count;
+        OptionsValue = Options.Create(optionsId);
+        (count > 0).Assert();
+        (elementType.CheckedReference == null).Assert();
+        (!elementType.IsHollow).Assert();
+        RepeaterAccessTypeCache = new(() => new(this));
+        NumberCache = new(() => new(this));
+    }
+
+    TypeBase IChild<TypeBase>.Parent => ElementType;
+
+    IEnumerable<IConversion> IForcedConversionProviderForPointer<ArrayReferenceType>.Result
+        (ArrayReferenceType destination)
+        => ForcedConversion(destination).NullableToArray();
+
+    TypeBase IRepeaterType.ElementType => ElementType;
+    TypeBase IRepeaterType.IndexType => Root.BitType.Number(IndexSize.ToInt());
+    bool IRepeaterType.IsMutable => IsMutable;
+
+    IImplementation ISymbolProviderForPointer<ArrayReference>.
+        Feature
+        (ArrayReference tokenClass)
+        => Feature.Extension.Value(ReferenceResult);
+
+    IImplementation ISymbolProviderForPointer<ConcatArrays>.
+        Feature(ConcatArrays tokenClass)
+        =>
+            Feature.Extension.FunctionFeature
+            (
+                (category, objectReference, argsType) =>
+                    ConcatArraysResult
+                    (
+                        category,
+                        objectReference,
+                        argsType,
+                        OptionsValue.IsMutable.SetTo(tokenClass.IsMutable)),
+                this);
+
+    IImplementation ISymbolProviderForPointer<Count>.Feature
+        (Count tokenClass)
+        => Feature.Extension.MetaFeature(CountResult);
+
+    IImplementation ISymbolProviderForPointer<DumpPrintToken>.
+        Feature
+        (DumpPrintToken tokenClass)
+        =>
+            OptionsValue.IsTextItem.Value
+                ? Feature.Extension.Value(DumpPrintTokenResult)
+                : Feature.Extension.Value(DumpPrintTokenArrayResult);
+
+    IImplementation ISymbolProviderForPointer<Mutable>.Feature
+        (Mutable tokenClass)
+        => Feature.Extension.Value(MutableResult);
+
+    IImplementation ISymbolProviderForPointer<TextItem>.Feature
+        (TextItem tokenClass)
+        => Feature.Extension.Value(TextItemResult);
+
+
+    IImplementation ISymbolProviderForPointer<ToNumberOfBase>.
+        Feature
+        (ToNumberOfBase tokenClass)
+        =>
+            OptionsValue.IsTextItem.Value
+                ? Feature.Extension.MetaFeature(ToNumberOfBaseResult)
+                : null;
+
+    [DisableDump]
+    internal override bool IsHollow => Count == 0 || ElementType.IsHollow;
+
+    internal override string DumpPrintText
+        => "(" + ElementType.DumpPrintText + ")*" + Count + OptionsValue.DumpPrintText;
+
+    [DisableDump]
+    internal override Size SimpleItemSize
+        =>
+            OptionsValue.IsTextItem.Value
+                ? ElementType.SimpleItemSize ?? Size
+                : base.SimpleItemSize;
+
+    [DisableDump]
+    internal override IImplementation FunctionDeclarationForPointerType
+        => Feature.Extension.FunctionFeature(ElementAccessResult);
+
+    internal override IEnumerable<string> DeclarationOptions
+        => base.DeclarationOptions.Concat(InternalDeclarationOptions);
+
+    internal override int? SmartArrayLength(TypeBase elementType)
+        => ElementType.IsConvertible(elementType)? Count : base.SmartArrayLength(elementType);
+
+    protected override Size GetSize() => ElementType.Size * Count;
+
+    internal override Result Copier(Category category)
+        => ElementType.ArrayCopier(category);
+
+    internal override Result Cleanup(Category category)
+        => ElementType.ArrayCleanup(category);
+
+    [DisableDump]
+    protected override IEnumerable<IConversion> StripConversions
+    {
+        get { yield return Feature.Extension.Conversion(NoTextItemResult); }
+    }
+
+    internal override Result ConstructorResult(Category category, TypeBase argsType)
+    {
+        if(category.IsNone)
+            return null;
+
+        if(argsType == VoidType)
+            return Result(category, () => CodeBase.BitsConst(Size, BitsConst.Convert(0)));
+
+        var function = argsType as IFunction;
+        if(function != null)
+            return ConstructorResult(category, function);
+
+        return base.ConstructorResult(category, argsType);
+    }
+
+    [DisableDump]
+    internal override Root Root => ElementType.Root;
+
+    protected override string GetNodeDump()
+        => ElementType.NodeDump + "*" + Count + OptionsValue.NodeDump;
+
+    protected override CodeBase DumpPrintCode() => ArgCode.DumpPrintText(SimpleItemSize);
+
+    [DisableDump]
+    RepeaterAccessType AccessType => RepeaterAccessTypeCache.Value;
+
+    [DisableDump]
+    internal bool IsMutable => OptionsValue.IsMutable.Value;
+
+    [DisableDump]
+    internal bool IsTextItem => OptionsValue.IsTextItem.Value;
+
+    [DisableDump]
+    internal NumberType Number => NumberCache.Value;
+
+    [DisableDump]
+    ArrayType NoTextItem => ElementType.Array(Count, OptionsValue.IsTextItem.SetTo(false));
+
+    [DisableDump]
+    internal ArrayType TextItem => ElementType.Array(Count, OptionsValue.IsTextItem.SetTo(true));
+
+    [DisableDump]
+    internal ArrayType Mutable => ElementType.Array(Count, OptionsValue.IsMutable.SetTo(true));
+
+    IEnumerable<string> InternalDeclarationOptions
+    {
+        get
         {
-            ElementType = elementType;
-            Count = count;
-            OptionsValue = Options.Create(optionsId);
-            (count > 0).Assert();
-            (elementType.CheckedReference == null).Assert();
-            (!elementType.IsHollow).Assert();
-            RepeaterAccessTypeCache = new ValueCache<RepeaterAccessType>
-                (() => new RepeaterAccessType(this));
-            NumberCache = new ValueCache<NumberType>(() => new NumberType(this));
+            NotImplementedMethod();
+            return null;
         }
-
-        [DisableDump]
-        internal TypeBase ElementType { get; }
-        internal int Count { get; }
-        Options OptionsValue { get; }
-
-        TypeBase IRepeaterType.ElementType => ElementType;
-        TypeBase IRepeaterType.IndexType => Root.BitType.Number(IndexSize.ToInt());
-        bool IRepeaterType.IsMutable => IsMutable;
-        [DisableDump]
-        RepeaterAccessType AccessType => RepeaterAccessTypeCache.Value;
-        [DisableDump]
-        internal bool IsMutable => OptionsValue.IsMutable.Value;
-        [DisableDump]
-        internal bool IsTextItem => OptionsValue.IsTextItem.Value;
-        [DisableDump]
-        internal NumberType Number => NumberCache.Value;
-        [DisableDump]
-        ArrayType NoTextItem => ElementType.Array(Count, OptionsValue.IsTextItem.SetTo(false));
-        [DisableDump]
-        internal ArrayType TextItem => ElementType.Array(Count, OptionsValue.IsTextItem.SetTo(true))
-            ;
-        [DisableDump]
-        internal ArrayType Mutable => ElementType.Array(Count, OptionsValue.IsMutable.SetTo(true));
-
-        internal ArrayReferenceType Reference(bool isForceMutable)
-            => ElementType.ArrayReference(ArrayReferenceType.Options.ForceMutable(isForceMutable));
-
-        [DisableDump]
-        internal override bool IsHollow => Count == 0 || ElementType.IsHollow;
-
-        internal override string DumpPrintText
-            => "(" + ElementType.DumpPrintText + ")*" + Count + OptionsValue.DumpPrintText;
-
-        [DisableDump]
-        internal override Size SimpleItemSize
-            =>
-                OptionsValue.IsTextItem.Value
-                    ? (ElementType.SimpleItemSize ?? Size)
-                    : base.SimpleItemSize
-            ;
-
-        IImplementation ISymbolProviderForPointer<DumpPrintToken>.
-            Feature
-            (DumpPrintToken tokenClass)
-            =>
-                OptionsValue.IsTextItem.Value
-                    ? Feature.Extension.Value(DumpPrintTokenResult)
-                    : Feature.Extension.Value(DumpPrintTokenArrayResult);
-
-        IImplementation ISymbolProviderForPointer<ConcatArrays>.
-            Feature(ConcatArrays tokenClass)
-            =>
-                Feature.Extension.FunctionFeature
-                    (
-                        (category, objectReference, argsType) =>
-                            ConcatArraysResult
-                                (
-                                    category,
-                                    objectReference,
-                                    argsType,
-                                    OptionsValue.IsMutable.SetTo(tokenClass.IsMutable)),
-                        this);
-
-        IImplementation ISymbolProviderForPointer<TextItem>.Feature
-            (TextItem tokenClass)
-            => Feature.Extension.Value(TextItemResult);
-
-        IImplementation ISymbolProviderForPointer<Mutable>.Feature
-            (Mutable tokenClass)
-            => Feature.Extension.Value(MutableResult);
-
-        [DisableDump]
-        internal override IImplementation FunctionDeclarationForPointerType
-            => Feature.Extension.FunctionFeature(ElementAccessResult);
-
-        internal override IEnumerable<string> DeclarationOptions
-            => base.DeclarationOptions.Concat(InternalDeclarationOptions);
-
-        IEnumerable<string> InternalDeclarationOptions
-        {
-            get
-            {
-                NotImplementedMethod();
-                return null;
-            }
-        }
-
-
-        IImplementation ISymbolProviderForPointer<ToNumberOfBase>.
-            Feature
-            (ToNumberOfBase tokenClass)
-            =>
-                OptionsValue.IsTextItem.Value
-                    ? Feature.Extension.MetaFeature(ToNumberOfBaseResult)
-                    : null;
-
-        IImplementation ISymbolProviderForPointer<ArrayReference>.
-            Feature
-            (ArrayReference tokenClass)
-            => Feature.Extension.Value(ReferenceResult);
-
-        internal override int? SmartArrayLength(TypeBase elementType)
-            => ElementType.IsConvertible(elementType) ? Count : base.SmartArrayLength(elementType);
-
-        IImplementation ISymbolProviderForPointer<Count>.Feature
-            (Count tokenClass)
-            => Feature.Extension.MetaFeature(CountResult);
-
-        IEnumerable<IConversion> IForcedConversionProviderForPointer<ArrayReferenceType>.Result
-            (ArrayReferenceType destination)
-            => ForcedConversion(destination).NullableToArray();
-
-        protected override Size GetSize() => ElementType.Size * Count;
-
-        internal override Result Copier(Category category)
-            => ElementType.ArrayCopier(category);
-
-        internal override Result Cleanup(Category category)
-            => ElementType.ArrayCleanup(category);
-
-        [DisableDump]
-        protected override IEnumerable<IConversion> StripConversions
-        {
-            get { yield return Feature.Extension.Conversion(NoTextItemResult); }
-        }
-
-        Result NoTextItemResult(Category category) => ResultFromPointer(category, NoTextItem);
-        Result TextItemResult(Category category) => ResultFromPointer(category, TextItem);
-        Result MutableResult(Category category) => ResultFromPointer(category, Mutable);
-
-        Result ReferenceResult(Category category)
-            => Reference(IsMutable).Result(category, ObjectResult);
-
-        internal override Result ConstructorResult(Category category, TypeBase argsType)
-        {
-            if(category.IsNone)
-                return null;
-
-            if(argsType == VoidType)
-                return Result(category, () => CodeBase.BitsConst(Size, BitsConst.Convert(0)));
-
-            var function = argsType as IFunction;
-            if(function != null)
-                return ConstructorResult(category, function);
-
-            return base.ConstructorResult(category, argsType);
-        }
-
-        Result ConstructorResult(Category category, IFunction function)
-        {
-            var indexType = BitType
-                .Number(BitsConst.Convert(Count).Size.ToInt())
-                .Align;
-            var constructorResult = function.Result(category.WithType, indexType);
-            var elements = Count
+    }
+
+    TypeBase ElementAccessType => ElementType.TypeForArrayElement;
+
+    [DisableDump]
+    TypeBase IndexType => Root.BitType.Number(IndexSize.ToInt());
+
+    Size IndexSize => Size.AutoSize(Count).Align(Root.DefaultRefAlignParam.AlignBits);
+
+    internal ArrayReferenceType Reference(bool isForceMutable)
+        => ElementType.ArrayReference(ArrayReferenceType.Options.ForceMutable(isForceMutable));
+
+    Result NoTextItemResult(Category category) => ResultFromPointer(category, NoTextItem);
+    Result TextItemResult(Category category) => ResultFromPointer(category, TextItem);
+    Result MutableResult(Category category) => ResultFromPointer(category, Mutable);
+
+    Result ReferenceResult(Category category)
+        => Reference(IsMutable).Result(category, ObjectResult);
+
+    Result ConstructorResult(Category category, IFunction function)
+    {
+        var indexType = BitType
+            .Number(BitsConst.Convert(Count).Size.ToInt())
+            .Align;
+        var constructorResult = function.Result(category.WithType, indexType);
+        var elements = Count
                 .Select(i => ElementConstructorResult(category, constructorResult, i, indexType))
-                .Aggregate((c, n) => n + c)
-                ?? VoidType.Result(category);
-            return Result(category, elements);
-        }
-
-        Result ElementConstructorResult
-            (Category category, Result elementConstructorResult, int i, TypeBase indexType)
-        {
-            var resultForArg = indexType
-                .Result
+                .Aggregate((c, n) => n + c) ??
+            VoidType.Result(category);
+        return Result(category, elements);
+    }
+
+    Result ElementConstructorResult
+        (Category category, Result elementConstructorResult, int i, TypeBase indexType)
+    {
+        var resultForArg = indexType
+            .Result
                 (category.WithType, () => CodeBase.BitsConst(indexType.Size, BitsConst.Convert(i)));
-            return elementConstructorResult
+        return elementConstructorResult
                 .ReplaceArg(resultForArg)
                 .Conversion(ElementAccessType)
-                .Conversion(ElementType)
-                & category;
-        }
-
-        TypeBase ElementAccessType => ElementType.TypeForArrayElement;
-
-        [DisableDump]
-        internal override Root Root => ElementType.Root;
-
-        [DisableDump]
-        TypeBase IndexType => Root.BitType.Number(IndexSize.ToInt());
-
-        Size IndexSize => Size.AutoSize(Count).Align(Root.DefaultRefAlignParam.AlignBits);
-
-        protected override string GetNodeDump()
-            => ElementType.NodeDump + "*" + Count + OptionsValue.NodeDump;
-
-        Result ConcatArraysResult
-            (
-            Category category,
-            IContextReference objectReference,
-            TypeBase argsType,
-            string argsOptions)
-        {
-            var oldElementsResult = Pointer
-                .Result(category.WithType, objectReference).DereferenceResult;
-
-            var isElementArg = argsType.IsConvertible(ElementAccessType);
-            var newCount = isElementArg ? 1 : argsType.ArrayLength(ElementAccessType);
-            var newElementsResultRaw
-                = isElementArg
-                    ? argsType.Conversion(category.WithType, ElementAccessType)
-                    : argsType.Conversion(category.WithType, ElementType.Array(newCount, argsOptions));
-
-            var newElementsResult = newElementsResultRaw.AutomaticDereferencedAlignedResult();
-            var result = ElementType
-                .Array(Count + newCount, argsOptions)
-                .Result(category, newElementsResult + oldElementsResult);
-            return result;
-        }
-
-        protected override CodeBase DumpPrintCode() => ArgCode.DumpPrintText(SimpleItemSize);
-
-        Result DumpPrintTokenArrayResult(Category category)
-        {
-            var result = Root.ConcatPrintResult(category, Count, DumpPrintResult);
-            if(category.HasCode)
-                result.Code = CodeBase.DumpPrintText
-                    ("<<" + (OptionsValue.IsMutable.Value ? ":=" : ""))
-                    + result.Code;
-            return result;
-        }
-
-        Result DumpPrintResult(Category category, int position)
-        {
-            return ElementType
-                .SmartPointer
-                .GenericDumpPrintResult(category)
-                .ReplaceAbsolute
-                (
-                    ElementType.Pointer.CheckedReference,
-                    c => ReferenceResult(c).AddToReference(() => ElementType.Size * position)
-                );
-        }
-
-        Result ElementAccessResult(Category category, TypeBase right)
-            => AccessType.Result(category, ObjectResult(category), right);
-
-        Result ToNumberOfBaseResult
-            (Category category, ResultCache left, ContextBase context, ValueSyntax right)
-        {
-            var target = (left & Category.All)
-                .AutomaticDereferencedAlignedResult()
-                .Evaluate(context.RootContext.ExecutionContext)
-                .ToString(ElementType.Size);
-            var conversionBase = right.Evaluate(context).ToInt32();
-            (conversionBase >= 2).Assert(conversionBase.ToString);
-            var result = BitsConst.Convert(target, conversionBase);
-            return Root.BitType.Result(category, result).Align;
-        }
-
-        Result CountResult
-            (Category category, ResultCache left, ContextBase context, ValueSyntax right)
-        {
-            (right == null).Assert();
-            return IndexType.Result
-                (category, () => CodeBase.BitsConst(IndexSize, BitsConst.Convert(Count)));
-        }
-
-        IConversion ForcedConversion(ArrayReferenceType destination)
-        {
-            if(!HasForcedConversion(destination))
-                return null;
-
-            return Feature.Extension.Conversion
-                (category => destination.ConversionResult(category, this), SmartPointer);
-        }
-
-        bool HasForcedConversion(ArrayReferenceType destination)
-        {
-            if(destination.IsMutable && !OptionsValue.IsMutable.Value)
-                return false;
-
-            if(ElementType == destination.ValueType)
-                return true;
-
-            NotImplementedMethod(destination);
+                .Conversion(ElementType) &
+            category;
+    }
+
+    Result ConcatArraysResult
+    (
+        Category category,
+        IContextReference objectReference,
+        TypeBase argsType,
+        string argsOptions
+    )
+    {
+        var oldElementsResult = Pointer
+            .Result(category.WithType, objectReference).DereferenceResult;
+
+        var isElementArg = argsType.IsConvertible(ElementAccessType);
+        var newCount = isElementArg? 1 : argsType.ArrayLength(ElementAccessType);
+        var newElementsResultRaw
+            = isElementArg
+                ? argsType.Conversion(category.WithType, ElementAccessType)
+                : argsType.Conversion(category.WithType, ElementType.Array(newCount, argsOptions));
+
+        var newElementsResult = newElementsResultRaw.AutomaticDereferencedAlignedResult();
+        var result = ElementType
+            .Array(Count + newCount, argsOptions)
+            .Result(category, newElementsResult + oldElementsResult);
+        return result;
+    }
+
+    Result DumpPrintTokenArrayResult(Category category)
+    {
+        var result = Root.ConcatPrintResult(category, Count, DumpPrintResult);
+        if(category.HasCode)
+            result.Code = CodeBase.DumpPrintText
+                    ("<<" + (OptionsValue.IsMutable.Value? ":=" : "")) +
+                result.Code;
+        return result;
+    }
+
+    Result DumpPrintResult(Category category, int position) => ElementType
+        .SmartPointer
+        .GenericDumpPrintResult(category)
+        .ReplaceAbsolute
+        (
+            ElementType.Pointer.CheckedReference,
+            c => ReferenceResult(c).AddToReference(() => ElementType.Size * position)
+        );
+
+    Result ElementAccessResult(Category category, TypeBase right)
+        => AccessType.Result(category, ObjectResult(category), right);
+
+    Result ToNumberOfBaseResult
+        (Category category, ResultCache left, ContextBase context, ValueSyntax right)
+    {
+        var target = (left & Category.All)
+            .AutomaticDereferencedAlignedResult()
+            .Evaluate(context.RootContext.ExecutionContext)
+            .ToString(ElementType.Size);
+        var conversionBase = right.Evaluate(context).ToInt32();
+        (conversionBase >= 2).Assert(conversionBase.ToString);
+        var result = BitsConst.Convert(target, conversionBase);
+        return Root.BitType.Result(category, result).Align;
+    }
+
+    Result CountResult
+        (Category category, ResultCache left, ContextBase context, ValueSyntax right)
+    {
+        (right == null).Assert();
+        return IndexType.Result
+            (category, () => CodeBase.BitsConst(IndexSize, BitsConst.Convert(Count)));
+    }
+
+    IConversion ForcedConversion(ArrayReferenceType destination)
+    {
+        if(!HasForcedConversion(destination))
+            return null;
+
+        return Feature.Extension.Conversion
+            (category => destination.ConversionResult(category, this), SmartPointer);
+    }
+
+    bool HasForcedConversion(ArrayReferenceType destination)
+    {
+        if(destination.IsMutable && !OptionsValue.IsMutable.Value)
             return false;
-        }
-
-        TypeBase IChild<TypeBase>.Parent => ElementType;
+
+        if(ElementType == destination.ValueType)
+            return true;
+
+        NotImplementedMethod(destination);
+        return false;
     }
 }


s 收发室地方

s 收发室地方

--- Hoyi/forms/FMEntityEditor.Designer.cs
+++ Hoyi/forms/FMEntityEditor.Designer.cs
@@ -165,13 +165,13 @@
             //
             this.splitContainer1.Panel2.Controls.Add(this.splitContainer3);
             this.splitContainer1.Size = new System.Drawing.Size(1218, 641);
-            this.splitContainer1.SplitterDistance = 65;
+            this.splitContainer1.SplitterDistance = 57;
             this.splitContainer1.TabIndex = 0;
             //
             // cmbsysfield
             //
             this.cmbsysfield.FormattingEnabled = true;
-            this.cmbsysfield.Location = new System.Drawing.Point(1032, 3);
+            this.cmbsysfield.Location = new System.Drawing.Point(591, 4);
             this.cmbsysfield.Name = "cmbsysfield";
             this.cmbsysfield.Size = new System.Drawing.Size(160, 20);
             this.cmbsysfield.TabIndex = 22;
@@ -199,12 +199,13 @@
             // chkNeedFPYTable
             //
             this.chkNeedFPYTable.AutoSize = true;
-            this.chkNeedFPYTable.Location = new System.Drawing.Point(630, 6);
+            this.chkNeedFPYTable.Location = new System.Drawing.Point(1146, 5);
             this.chkNeedFPYTable.Name = "chkNeedFPYTable";
             this.chkNeedFPYTable.Size = new System.Drawing.Size(108, 16);
             this.chkNeedFPYTable.TabIndex = 18;
             this.chkNeedFPYTable.Text = "Need FPY Table";
             this.chkNeedFPYTable.UseVisualStyleBackColor = true;
+            this.chkNeedFPYTable.Visible = false;
             this.chkNeedFPYTable.CheckedChanged += new System.EventHandler(this.chkNeedFPYTable_CheckedChanged);
             //
             // cmbMySQLDataType
@@ -218,14 +219,14 @@
             // cmbTemplate
             //
             this.cmbTemplate.FormattingEnabled = true;
-            this.cmbTemplate.Location = new System.Drawing.Point(300, 4);
+            this.cmbTemplate.Location = new System.Drawing.Point(820, 4);
             this.cmbTemplate.Name = "cmbTemplate";
             this.cmbTemplate.Size = new System.Drawing.Size(160, 20);
             this.cmbTemplate.TabIndex = 15;
             //
             // btnAddModelAttrs
             //
-            this.btnAddModelAttrs.Location = new System.Drawing.Point(466, 2);
+            this.btnAddModelAttrs.Location = new System.Drawing.Point(986, 1);
             this.btnAddModelAttrs.Name = "btnAddModelAttrs";
             this.btnAddModelAttrs.Size = new System.Drawing.Size(154, 23);
             this.btnAddModelAttrs.TabIndex = 14;
@@ -281,8 +282,8 @@
             // splitContainer3.Panel2
             //
             this.splitContainer3.Panel2.Controls.Add(this.splitContainer4);
-            this.splitContainer3.Size = new System.Drawing.Size(1218, 572);
-            this.splitContainer3.SplitterDistance = 350;
+            this.splitContainer3.Size = new System.Drawing.Size(1218, 580);
+            this.splitContainer3.SplitterDistance = 354;
             this.splitContainer3.TabIndex = 0;
             //
             // tabControl1
@@ -294,7 +295,7 @@
             this.tabControl1.Location = new System.Drawing.Point(0, 0);
             this.tabControl1.Name = "tabControl1";
             this.tabControl1.SelectedIndex = 0;
-            this.tabControl1.Size = new System.Drawing.Size(1218, 350);
+            this.tabControl1.Size = new System.Drawing.Size(1218, 354);
             this.tabControl1.TabIndex = 15;
             //
             // tabPage1
@@ -303,7 +304,7 @@
             this.tabPage1.Location = new System.Drawing.Point(4, 22);
             this.tabPage1.Name = "tabPage1";
             this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
-            this.tabPage1.Size = new System.Drawing.Size(1210, 324);
+            this.tabPage1.Size = new System.Drawing.Size(1210, 328);
             this.tabPage1.TabIndex = 0;
             this.tabPage1.Text = "Attributes";
             this.tabPage1.UseVisualStyleBackColor = true;
@@ -330,8 +331,8 @@
             this.splitContainer2.Panel2.Controls.Add(this.btnDeleteAttr);
             this.splitContainer2.Panel2.Controls.Add(this.btnEditAttr);
             this.splitContainer2.Panel2.Controls.Add(this.btnAddAttr);
-            this.splitContainer2.Size = new System.Drawing.Size(1204, 318);
-            this.splitContainer2.SplitterDistance = 283;
+            this.splitContainer2.Size = new System.Drawing.Size(1204, 322);
+            this.splitContainer2.SplitterDistance = 286;
             this.splitContainer2.TabIndex = 0;
             //
             // gridAttributes
@@ -341,7 +342,7 @@
             this.gridAttributes.Location = new System.Drawing.Point(0, 0);
             this.gridAttributes.Name = "gridAttributes";
             this.gridAttributes.RowTemplate.Height = 23;
-            this.gridAttributes.Size = new System.Drawing.Size(1204, 283);
+            this.gridAttributes.Size = new System.Drawing.Size(1204, 286);
             this.gridAttributes.TabIndex = 0;
             this.gridAttributes.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.gridAttributes_CellClick);
             this.gridAttributes.RowHeaderMouseDoubleClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.gridAttributes_RowHeaderMouseDoubleClick);
@@ -694,8 +695,8 @@
             // splitContainer4.Panel2
             //
             this.splitContainer4.Panel2.Controls.Add(this.tabControl2);
-            this.splitContainer4.Size = new System.Drawing.Size(1218, 218);
-            this.splitContainer4.SplitterDistance = 65;
+            this.splitContainer4.Size = new System.Drawing.Size(1218, 222);
+            this.splitContainer4.SplitterDistance = 66;
             this.splitContainer4.TabIndex = 0;
             //
             // chkPrimaryKey
@@ -749,7 +750,7 @@
             this.tabControl2.Location = new System.Drawing.Point(0, 0);
             this.tabControl2.Name = "tabControl2";
             this.tabControl2.SelectedIndex = 0;
-            this.tabControl2.Size = new System.Drawing.Size(1218, 149);
+            this.tabControl2.Size = new System.Drawing.Size(1218, 152);
             this.tabControl2.TabIndex = 0;
             //
             // tabPage5
@@ -770,7 +771,7 @@
             this.tabPage5.Location = new System.Drawing.Point(4, 22);
             this.tabPage5.Name = "tabPage5";
             this.tabPage5.Padding = new System.Windows.Forms.Padding(3);
-            this.tabPage5.Size = new System.Drawing.Size(1210, 123);
+            this.tabPage5.Size = new System.Drawing.Size(1210, 126);
             this.tabPage5.TabIndex = 0;
             this.tabPage5.Text = "DataType";
             //
@@ -952,7 +953,7 @@
             // cmbchecktemplate
             //
             this.cmbchecktemplate.FormattingEnabled = true;
-            this.cmbchecktemplate.Location = new System.Drawing.Point(802, 4);
+            this.cmbchecktemplate.Location = new System.Drawing.Point(361, 4);
             this.cmbchecktemplate.Name = "cmbchecktemplate";
             this.cmbchecktemplate.Size = new System.Drawing.Size(160, 20);
             this.cmbchecktemplate.TabIndex = 23;
@@ -962,7 +963,7 @@
             // label16
             //
             this.label16.AutoSize = true;
-            this.label16.Location = new System.Drawing.Point(741, 6);
+            this.label16.Location = new System.Drawing.Point(300, 8);
             this.label16.Name = "label16";
             this.label16.Size = new System.Drawing.Size(59, 12);
             this.label16.TabIndex = 24;
@@ -971,7 +972,7 @@
             // label17
             //
             this.label17.AutoSize = true;
-            this.label17.Location = new System.Drawing.Point(968, 6);
+            this.label17.Location = new System.Drawing.Point(758, 8);
             this.label17.Name = "label17";
             this.label17.Size = new System.Drawing.Size(59, 12);
             this.label17.TabIndex = 24;
@@ -980,7 +981,7 @@
             // label18
             //
             this.label18.AutoSize = true;
-            this.label18.Location = new System.Drawing.Point(968, 6);
+            this.label18.Location = new System.Drawing.Point(528, 8);
             this.label18.Name = "label18";
             this.label18.Size = new System.Drawing.Size(59, 12);
             this.label18.TabIndex = 24;


limited keypad to 4 numbers input

limited keypad to 4 numbers input

--- IAT445/Assets/Scripts/Keypad.cs
+++ IAT445/Assets/Scripts/Keypad.cs
@@ -64,7 +64,8 @@
 			_currentInput = string.Empty;

 		} else {
-			_currentInput += keyValue;
+
+			_currentInput += _currentInput.Length < 4 ? keyValue : "";
 		}
 		_keypadInput.text = _currentInput;
 	}


forceModuleActive is now deprecated

forceModuleActive is now deprecated

--- Assets/MRTK/Tests/TestUtilities/PlayModeTestUtilities.cs
+++ Assets/MRTK/Tests/TestUtilities/PlayModeTestUtilities.cs
@@ -220,7 +220,10 @@
                 {
                     CameraCache.Main.gameObject.AddComponent<MixedRealityInputModule>();
                 }
+
+#if !UNITY_2021_1_OR_NEWER
                 inputModule.forceModuleActive = true;
+#endif // !UNITY_2021_1_OR_NEWER
             }
         }


Some comments from Troy

Some comments from Troy

--- Assets/MixedRealityToolkit/Utilities/CameraFOVChecker.cs
+++ Assets/MixedRealityToolkit/Utilities/CameraFOVChecker.cs
@@ -37,15 +37,14 @@
                 return false;
             }

+            var cameraColliderPair = (collider: myCollider, camera: cam);
+            bool result = false;
             if (inFOVConeLastCalculatedFrame != Time.frameCount)
             {
                 inFOVConeColliderCache.Clear();
                 inFOVConeLastCalculatedFrame = Time.frameCount;
-            }
-            var cameraColliderPair = (collider: myCollider, camera: cam);
-            if (inFOVConeColliderCache.TryGetValue(cameraColliderPair, out bool result))
+            } else if (inFOVConeColliderCache.TryGetValue(cameraColliderPair, out result))
             {
-                Debug.Log($"Cache hit! Returning {result}");
                 return result;
             }

@@ -71,8 +70,6 @@
                 zMax = Mathf.Max(zMax, corner.z);
             }

-            // edge case: check if camera is inside the entire bounds of the collider;
-            // Consider simplifying to myCollider.bounds.Contains(CameraCache.main.transform.position)
             var cameraPos = cam.transform.position;
             result = xMin <= cameraPos.x && cameraPos.x <= xMax
                 && yMin <= cameraPos.y && cameraPos.y <= yMax


Set up PuzzleMaster for playing sounds

Set up PuzzleMaster for playing sounds

--- Assets/OCDRoomEscape/Scripts/Interaction/PuzzleMaster.cs
+++ Assets/OCDRoomEscape/Scripts/Interaction/PuzzleMaster.cs
@@ -36,8 +36,9 @@
 		}

 		var growthIncrement = puzzle.puzzleWeight / weightedIncrementTotal;
-		// TODO: Notify room of growth increment
+		// Notify room of growth increment
 		wallMgr.Resize(wallMgr.transformRoom + growthIncrement);
+		KickOffSoundForPuzzle(puzzle);

 		if (puzzle.IsResetable() && puzzles.Contains(puzzle)) {
 			Debug.Log("Puzzle marked for reset");


Fixed line endings

Fixed line endings

--- ILRepack/DocumentationMerger.cs
+++ ILRepack/DocumentationMerger.cs
@@ -1,68 +1,68 @@
 using System;
 using System.Collections.Generic;
 using System.IO;
-using System.Xml;
-using System.Xml.XPath;
+using System.Xml;
+using System.Xml.XPath;
 using Mono.Cecil;

-namespace ILRepacking
-{
+namespace ILRepacking
+{
     internal static class DocumentationMerger
-    {
+    {
         internal static void Process(ILRepack repack)
         {
-            try
-            {
-                var validXmlFiles = new List<XmlDocument>();
-                XmlDocument doc;
+            try
+            {
+                var validXmlFiles = new List<XmlDocument>();
+                XmlDocument doc;
                 foreach (string assembly in repack.MergedAssemblyFiles)
                 {
                     string assemblyDoc = Path.ChangeExtension(assembly, ".xml");
                     if (File.Exists (assemblyDoc))
-                    {
+                    {
                         doc = new XmlDocument();
-                        doc.Load (assemblyDoc);
+                        doc.Load (assemblyDoc);
                         validXmlFiles.Add(doc);
                     }
                 }

                 if (validXmlFiles.Count == 0)
-                    return;
-
-                doc = new XmlDocument();
-                XmlElement root = doc.CreateElement("doc");
-                doc.AppendChild(root);
-
-                // assembly name
-                var node = doc.CreateElement("assembly");
-                root.AppendChild(node);
-                var node2 = doc.CreateElement("name");
-                node.AppendChild(node2);
-                node2.AppendChild(doc.CreateTextNode(repack.TargetAssemblyDefinition.Name.Name));
-
-                // members
-                node = doc.CreateElement("members");
-                root.AppendChild(node);
-                foreach (var xml in validXmlFiles)
-                {
-                    XPathNodeIterator iterator = xml.CreateNavigator().Select("/doc/members/member");
-                    while (iterator.MoveNext())
-                    {
-                        XPathNavigator navigator = iterator.Current;
-                        node.AppendChild(doc.ImportNode((XmlNode) navigator.UnderlyingObject, true));
-                    }
-                }
-
-                // write
-                using (var writer = XmlWriter.Create(Path.ChangeExtension(repack.OutputFile, ".xml"), new XmlWriterSettings() { Indent = true, IndentChars = "    " }))
-                {
-                    doc.WriteTo(writer);
+                    return;
+
+                doc = new XmlDocument();
+                XmlElement root = doc.CreateElement("doc");
+                doc.AppendChild(root);
+
+                // assembly name
+                var node = doc.CreateElement("assembly");
+                root.AppendChild(node);
+                var node2 = doc.CreateElement("name");
+                node.AppendChild(node2);
+                node2.AppendChild(doc.CreateTextNode(repack.TargetAssemblyDefinition.Name.Name));
+
+                // members
+                node = doc.CreateElement("members");
+                root.AppendChild(node);
+                foreach (var xml in validXmlFiles)
+                {
+                    XPathNodeIterator iterator = xml.CreateNavigator().Select("/doc/members/member");
+                    while (iterator.MoveNext())
+                    {
+                        XPathNavigator navigator = iterator.Current;
+                        node.AppendChild(doc.ImportNode((XmlNode) navigator.UnderlyingObject, true));
+                    }
                 }
-            }
-            catch (Exception e)
-            {
-                repack.ERROR("Failed to merge documentation files: " + e);
+
+                // write
+                using (var writer = XmlWriter.Create(Path.ChangeExtension(repack.OutputFile, ".xml"), new XmlWriterSettings() { Indent = true, IndentChars = "    " }))
+                {
+                    doc.WriteTo(writer);
+                }
+            }
+            catch (Exception e)
+            {
+                repack.ERROR("Failed to merge documentation files: " + e);
             }
         }
-    }
-}
+    }
+}


Refactor

Refactor

--- Bellona/Analysis/Analysis/Clustering/ClusteringHelper.cs
+++ Bellona/Analysis/Analysis/Clustering/ClusteringHelper.cs
@@ -31,10 +31,13 @@
         {
             var current = clusters;

-            Enumerable2.Repeat(true, maxIterations)
-                .Select(_ => TrainOnce(current, records))
-                .TakeWhile(cs => !ClustersEquals(current, cs))
-                .Execute(cs => current = cs);
+            foreach (var _ in Enumerable2.Repeat(true, maxIterations))
+            {
+                var cs = TrainOnce(current, records);
+                if (ClustersEquals(current, cs)) return current;
+
+                current = cs;
+            }

             return current;
         }
@@ -44,14 +47,16 @@
             var maxClustersNumber2 = maxClustersNumber.HasValue ? Math.Min(maxClustersNumber.Value, records.Count) : records.Count;
             var current = clusters;

-            Enumerable2.Repeat(true)
-                .Do(_ => current = TrainForNumber(current, records, null))
-                .TakeWhile(_ => current.Length < maxClustersNumber2)
-                .Select(_ => SeparateClustersIfLoose(current, maxStandardScore))
-                .TakeWhile(cs => current != cs)
-                .Execute(cs => current = cs);
+            while (true)
+            {
+                current = TrainForNumber(current, records, null);
+                if (current.Length >= maxClustersNumber2) return current;

-            return current;
+                var farthestRecord = GetFarthestRecord(current);
+                if (farthestRecord.StandardScore <= maxStandardScore) return current;
+
+                current = SeparateClusters(current, farthestRecord.Element);
+            }
         }

         public static Cluster<T> AssignFeatures<T>(Cluster<T>[] clusters, ArrayVector features)
@@ -80,14 +85,6 @@
                 .All(i => cluster1.Records[i] == cluster2.Records[i]);
         }

-        public static Cluster<T>[] SeparateClustersIfLoose<T>(Cluster<T>[] clusters, double maxStandardScore)
-        {
-            var farthestRecord = GetFarthestRecord(clusters);
-            return farthestRecord.StandardScore <= maxStandardScore
-                ? clusters
-                : SeparateClusters(clusters, farthestRecord.Element);
-        }
-
         public static Cluster<T>[] SeparateClusters<T>(Cluster<T>[] clusters, ClusteringRecord<T> recordForNewCluster)
         {
             return clusters


Created fix for when computer is not in sccm

--- ITSWebMgmt/ComputerInfo.aspx.cs
+++ ITSWebMgmt/ComputerInfo.aspx.cs
@@ -373,19 +373,35 @@
             var searcher = new ManagementObjectSearcher(ms, wqlq);

             ManagementObject obj = new ManagementObject();
-
-
-            foreach (ManagementObject o in searcher.Get())
-            {
-                //o.Properties["ResourceID"].Value.ToString();
-                var collectionID = o.Properties["CollectionID"].Value.ToString();
-                var pathString = "\\\\srv-cm12-p01.srv.aau.dk\\ROOT\\SMS\\site_AA1" + ":SMS_Collection.CollectionID=\"" + collectionID + "\"";
-                ManagementPath path = new ManagementPath(pathString);
-
-                obj.Path = path;
-                obj.Get();
-
-                sb.Append(string.Format("{0}
", obj["Name"]));
+            var results = searcher.Get();
+
+            bool hasValues=false;
+            try
+            {
+                var t = results.Count;
+                hasValues=true;
+            }catch (ManagementException e){
+
+            }
+
+            if (hasValues)
+            {
+                foreach (ManagementObject o in results)
+                {
+                    //o.Properties["ResourceID"].Value.ToString();
+                    var collectionID = o.Properties["CollectionID"].Value.ToString();
+                    var pathString = "\\\\srv-cm12-p01.srv.aau.dk\\ROOT\\SMS\\site_AA1" + ":SMS_Collection.CollectionID=\"" + collectionID + "\"";
+                    ManagementPath path = new ManagementPath(pathString);
+
+                    obj.Path = path;
+                    obj.Get();
+
+                    sb.Append(string.Format("{0}
", obj["Name"]));
+                }
+            }
+            else
+            {
+                sb.Append("Computer not found i SCCM");
             }


Search images recursively

Search images recursively

--- ImageCrusher/FrmImageCrusher.cs
+++ ImageCrusher/FrmImageCrusher.cs
@@ -67,56 +67,84 @@
                 return;
             }

-            String destPath = String.Format("{0}/small", path);
+            String destPath;
+            if (path.EndsWith("/") || path.EndsWith("\\"))
+            {
+                path = path.Substring(0, path.Length - 1);
+            }
+            destPath = String.Format("{0}/small", path);
+            string currentPath = path;
+
             int size = InitialSize;

             lstImagenes_Clean();

-            string[] fileNames = Directory.GetFiles(path);
-            foreach (string fileName in fileNames)
-            {
-                string ext = Path.GetExtension(fileName).ToLower();
-                if (ext == ".png" || ext == ".jpg" || ext == ".jpeg")
-                {
-                    try
-                    {
-                        Image img = Image.FromFile(fileName);
-                        int width = img.Width;
-                        int height = img.Height;
-                        if (width > height)
-                        {
-                            height = (int)(height / (width / (double)size));
-                            width = size;
-                        }
-                        else
-                        {
-                            width = (int)(width / (height / (double)size));
-                            height = size;
-                        }
-
-                        if (!Directory.Exists(destPath))
-                        {
-                            Directory.CreateDirectory(destPath);
-                        }
-
-                        Image imgThumb = Image_Resize(img, width, height);
-                        string newFileName = String.Format("{0}/{1}.small.jpg", destPath, Path.GetFileNameWithoutExtension(fileName));
-                        imgThumb.Save(newFileName, ImageFormat.Jpeg);
-
-                        // Hack: collect garbage now
-                        GC.Collect();
-
-                        lstImagenes_AddLine(string.Format("OK: {0}", newFileName));
-                    }
-                    catch (Exception ex)
-                    {
-                        lstImagenes_AddLine(string.Format("Error: {0} {1}", fileName, ex.Message));
-                    }
-                }
-            }
+            ProcessDirectory(currentPath, path, destPath, size);
             lstImagenes_AddLine("End.");
         }

+        private void ProcessDirectory(string currentPath, string path, string destPath, int size)
+        {
+            string[] fileNames = Directory.GetFiles(currentPath);
+            foreach (string fileName in fileNames)
+            {
+                ProcessFile(fileName, path, destPath, size);
+            }
+            string[] directories = Directory.GetDirectories(currentPath);
+            foreach (string directory in directories)
+            {
+                ProcessDirectory(directory, path, destPath, size);
+            }
+        }
+
+        private void ProcessFile(string fileName, string path, string destPath, int size)
+        {
+            string ext = Path.GetExtension(fileName).ToLower();
+            if (ext == ".png" || ext == ".jpg" || ext == ".jpeg")
+            {
+                try
+                {
+                    Image img = Image.FromFile(fileName);
+                    Image imgThumb = Image_GenerateThumbnail(img, size);
+
+                    string fileDirectory = Path.GetDirectoryName(fileName);
+                    fileDirectory = fileDirectory.Replace(path, destPath);
+                    if (!Directory.Exists(fileDirectory))
+                    {
+                        Directory.CreateDirectory(fileDirectory);
+                    }
+                    string newFileName = String.Format("{0}/{1}.small.jpg", fileDirectory, Path.GetFileNameWithoutExtension(fileName));
+                    imgThumb.Save(newFileName, ImageFormat.Jpeg);
+
+                    // Hack: collect garbage now
+                    GC.Collect();
+
+                    lstImagenes_AddLine(string.Format("OK: {0}", newFileName));
+                }
+                catch (Exception ex)
+                {
+                    lstImagenes_AddLine(string.Format("Error: {0} {1}", fileName, ex.Message));
+                }
+            }
+        }
+
+        private Image Image_GenerateThumbnail(Image img, int size)
+        {
+            int width = img.Width;
+            int height = img.Height;
+            if (width > height)
+            {
+                height = (int)(height / (width / (double)size));
+                width = size;
+            }
+            else
+            {
+                width = (int)(width / (height / (double)size));
+                height = size;
+            }
+            Image imgThumb = Image_Resize(img, width, height);
+            return imgThumb;
+        }

         public Image Image_Resize(Image img, int width, int height)
         {


Fixes skip type converter.

Fixes skip type converter.

--- Inga/Inga/Configuration/Task.cs
+++ Inga/Inga/Configuration/Task.cs
@@ -22,6 +22,7 @@
         public int Retention => int.Parse(this["retention"].ToString());

         [ConfigurationProperty("skip", IsRequired = false)]
+        [TypeConverter(typeof(CommaDelimitedStringCollectionConverter))]
         public CommaDelimitedStringCollection Skip => this["skip"] as CommaDelimitedStringCollection;

         [ConfigurationProperty("on", IsRequired = false)]


Continue to refactor the SOR towards hexagonal

--- CSharp/SimpleOrderRouting.Infra/MarketGatewaysAdapter.cs
+++ CSharp/SimpleOrderRouting.Infra/MarketGatewaysAdapter.cs
@@ -15,6 +15,7 @@

         public MarketGatewaysAdapter(MarketGateway[] marketGateways)
         {
+
             throw new NotImplementedException();
         }


Implementing a test with a mock IDataReader

--- Chauffeur.Tests/Deliverables/DeliveryDeliverableTests.cs
+++ Chauffeur.Tests/Deliverables/DeliveryDeliverableTests.cs
@@ -114,7 +114,6 @@
         }

         [Test]
-        [NUnit.Framework.Ignore]
         public async Task FoundDeliveryPreviouslyRun_WillBeSkipped()
         {
             var provider = Substitute.For<ISqlSyntaxProvider>();
@@ -134,8 +133,15 @@
             reader.Read().Returns(true, false);
             reader.GetBoolean(Arg.Any<int>()).Returns(true);
             reader.GetInt32(Arg.Any<int>()).Returns(1);
+            reader.GetString(Arg.Any<int>()).Returns(string.Empty);
+            reader.GetDateTime(Arg.Any<int>()).Returns(DateTime.Now);
+            reader.GetValue(Arg.Any<int>()).Returns(DateTime.Now);
+            reader.FieldCount.Returns(5); //the number of properties on the table
+            reader.GetName(Arg.Any<int>()).Returns("Id", "Name", "ExecutionDate", "SignedFor", "Hash");
+            reader.GetFieldType(Arg.Any<int>()).Returns(typeof(int), typeof(string), typeof(DateTime), typeof(bool), typeof(string));
             var cmd = Substitute.For<IDbCommand>();
             cmd.ExecuteReader().Returns(reader);
+            cmd.ExecuteScalar().Returns(1);
             var conn = Substitute.For<IDbConnection>();
             conn.CreateCommand().Returns(cmd);
             var db = new UmbracoDatabase(conn);
@@ -155,7 +161,7 @@

             await deliverable.Run(null, null);

-            host.Received(1).Run(Arg.Any<string[]>());
+            host.Received(0).Run(Arg.Any<string[]>());
         }
     }
 }


Remove debug settings and dead code that is no longer necessary.

--- Client/Systems/VesselPositionSys/VesselPositionUpdate.cs
+++ Client/Systems/VesselPositionSys/VesselPositionUpdate.cs
@@ -227,11 +227,6 @@
                     //by the rotation, but not translate them.
                     Vessel.SetRotation(targetTransformRot, true);
                     Vessel.vesselTransform.rotation = targetTransformRot;
-
-                    if(SettingsSystem.CurrentSettings.Debug6)
-                    {
-                        Vessel.precalc.SetLandedPosRot();
-                    }
                 }
             }
         }
@@ -299,58 +294,51 @@
                 Vessel.protoVessel.altitude = altitude;

                 Vector3d position = Body.GetWorldSurfacePosition(latitude, longitude, altitude);
-                if (true || SettingsSystem.CurrentSettings.Debug6)
-                {
-                    Vector3 currentPosition = Vessel.vesselTransform.position;
-                    double cur_x = currentPosition.x;
-                    double cur_y = currentPosition.y;
-                    double cur_z = currentPosition.z;
-
-                    //We use a tolerance because the coordinate systems do not perfectly match between clients.
-                    //If the vessel is landed, use a higher tolerance because we want to avoid jitter.  This will cause landed vessels to "jump", but not wiggle and explode.
-                    double tolerance = Vessel.Landed ? .1 : .01;
-
-                    if (Math.Abs(position.x-cur_x) > tolerance || Math.Abs(position.y-cur_y) > tolerance || Math.Abs(position.z-cur_z) > tolerance) {
-                        Vessel.SetPosition(position);
-                    }
+                Vector3 currentPosition = Vessel.vesselTransform.position;
+                double cur_x = currentPosition.x;
+                double cur_y = currentPosition.y;
+                double cur_z = currentPosition.z;
+
+                //We use a tolerance because the coordinate systems do not perfectly match between clients.
+                //If the vessel is landed, use a higher tolerance because we want to avoid jitter.  This will cause landed vessels to "jump", but not wiggle and explode.
+                double tolerance = Vessel.Landed ? .1 : .01;
+
+                if (Math.Abs(position.x - cur_x) > tolerance || Math.Abs(position.y - cur_y) > tolerance || Math.Abs(position.z - cur_z) > tolerance)
+                {
+                    Vessel.SetPosition(position);
                 }
             }

-            if (SettingsSystem.CurrentSettings.Debug8)
-            {
-                //Set the velocity on each part and its rigidbody (if it exists)
-                //Vector3d vesselUniverseVelocity = (Vessel.orbit.GetVel() - (!Vessel.orbit.referenceBody.inverseRotation ? Vector3d.zero : Vessel.orbit.referenceBody.getRFrmVel(Vessel.vesselTransform.position)));
-                //Vector3d vel = vesselUniverseVelocity - Krakensbane.GetFrameVelocity();
-                int numParts = Vessel.Parts.Count;
-                for (int i = 0; i < numParts; i++)
-                {
-                    Part item = this.Vessel.parts[i];
-                    item.ResumeVelocity();
-
-                    //This is based on the behavior of Part.ResumeVelocity()
-                    //item.vel = Vector3.zero;
-                    //if (!Vessel.LandedOrSplashed)
-                    //{
-                    //    Vector3 partUniverseVelocity = (item.orbit.GetVel() - (!item.orbit.referenceBody.inverseRotation ? Vector3d.zero : item.orbit.referenceBody.getRFrmVel(item.partTransform.position)));
-                    //    Vector3 newVelocity = partUniverseVelocity - Krakensbane.GetFrameVelocity();
-                    //    item.vel = newVelocity;
-                    //}
-                    //if (item.rb != null)
-                    //{
-                    //    item.rb.velocity = item.vel;
-                    //}
-                }
-                Vessel.angularVelocityD = Vector3d.zero;
-                Vessel.angularVelocity = Vector3.zero;
-            }
+            //Set the velocity on each part and its rigidbody (if it exists)
+            //Vector3d vesselUniverseVelocity = (Vessel.orbit.GetVel() - (!Vessel.orbit.referenceBody.inverseRotation ? Vector3d.zero : Vessel.orbit.referenceBody.getRFrmVel(Vessel.vesselTransform.position)));
+            //Vector3d vel = vesselUniverseVelocity - Krakensbane.GetFrameVelocity();
+            int numParts = Vessel.Parts.Count;
+            for (int i = 0; i < numParts; i++)
+            {
+                Part item = this.Vessel.parts[i];
+                item.ResumeVelocity();
+
+                //This is based on the behavior of Part.ResumeVelocity()
+                //item.vel = Vector3.zero;
+                //if (!Vessel.LandedOrSplashed)
+                //{
+                //    Vector3 partUniverseVelocity = (item.orbit.GetVel() - (!item.orbit.referenceBody.inverseRotation ? Vector3d.zero : item.orbit.referenceBody.getRFrmVel(item.partTransform.position)));
+                //    Vector3 newVelocity = partUniverseVelocity - Krakensbane.GetFrameVelocity();
+                //    item.vel = newVelocity;
+                //}
+                //if (item.rb != null)
+                //{
+                //    item.rb.velocity = item.vel;
+                //}
+            }
+            Vessel.angularVelocityD = Vector3d.zero;
+            Vessel.angularVelocity = Vector3.zero;

             counter++;
-            if (SettingsSystem.CurrentSettings.Debug6 && (Vessel.altitude > 25000 || counter > 75))
+            if (Vessel.altitude > 25000 || counter > 75)
             {
                 counter = 0;
                 //Vessel.orbitDriver.updateFromParameters();
-                //After a single position update, reset the flag so that it only does one update per debug9 click
-                //SettingsSystem.CurrentSettings.Debug9 = false;
             }

             if (Vessel.loaded && !Vessel.packed)


Just don't call SetPosition it's shitty and makes jittering

--- Client/Systems/VesselPositionSys/VesselPositionUpdate.cs
+++ Client/Systems/VesselPositionSys/VesselPositionUpdate.cs
@@ -384,20 +384,13 @@
             Vessel.Landed = LerpPercentage < 0.5 ? Landed : Target.Landed;
             Vessel.Splashed = LerpPercentage < 0.5 ? Splashed : Target.Splashed;

-            if (Vessel.situation <= Vessel.Situations.SPLASHED)
+            if (Vessel.LandedOrSplashed)
             {
                 Vessel.latitude = LunaMath.Lerp(LatLonAlt[0], Target.LatLonAlt[0], LerpPercentage);
                 Vessel.longitude = LunaMath.Lerp(LatLonAlt[1], Target.LatLonAlt[1], LerpPercentage);
                 Vessel.altitude = LunaMath.Lerp(LatLonAlt[2], Target.LatLonAlt[2], LerpPercentage);

                 Vessel.SetPosition(Body.GetWorldSurfacePosition(Vessel.latitude, Vessel.longitude, Vessel.altitude));
-            }
-            else if (Vessel.situation <= Vessel.Situations.FLYING)
-            {
-                var startSurfacePos = Body.GetWorldSurfacePosition(LatLonAlt[0], LatLonAlt[1], LatLonAlt[2]);
-                var endSurfacePos = Body.GetWorldSurfacePosition(Target.LatLonAlt[0], Target.LatLonAlt[1], Target.LatLonAlt[2]);
-
-                Vessel.SetPosition(Vector3d.Lerp(startSurfacePos, endSurfacePos, LerpPercentage));
             }

             foreach (var part in Vessel.Parts)


NRE fix

NRE fix

--- Client/Systems/VesselPositionSys/VesselPositionUpdate.cs
+++ Client/Systems/VesselPositionSys/VesselPositionUpdate.cs
@@ -115,7 +115,7 @@
         public void Restart()
         {
             RestartRequested = true;
-            TimeStamp = Target.TimeStamp;
+            TimeStamp = Target?.TimeStamp ?? TimeStamp;
             ResetFields();
         }


git-svn-id: https://jumony.svn.codeplex.com/svn/trunk@64325 2327b42d-5241-43d6-9e2a-de5ac946f064

--- Ivony.Html.Web/JumonyHandler.cs
+++ Ivony.Html.Web/JumonyHandler.cs
@@ -40,7 +40,7 @@

       if ( MapperResult == null )
       {
-        Trace.Warn( "Web", "origin url is not found." );
+        Trace.Warn( "Core", "origin url is not found." );

         var builder = new UriBuilder( Request.Url );
         var path = builder.Path;
@@ -50,7 +50,7 @@

         builder.Path = path.Remove( path.Length - 5 );

-        Trace.Warn( "Web", "redirect to template vitual path." );
+        Trace.Warn( "Core", "redirect to template vitual path." );
         Response.Redirect( builder.Uri.AbsoluteUri );
       }


Implemented routing configuration handling for Cisco XR

--- Jovice.Common/Necrow/PEProbe.cs
+++ Jovice.Common/Necrow/PEProbe.cs
@@ -181,6 +181,81 @@

     }

+    class PERouteUseToDatabase : ToDatabase
+    {
+        private string type;
+
+        public string Type
+        {
+            get { return type; }
+            set { type = value; }
+        }
+
+        private string routeNameID;
+
+        public string RouteNameID
+        {
+            get { return routeNameID; }
+            set { routeNameID = value; }
+        }
+
+        private string network;
+
+        public string Network
+        {
+            get { return network; }
+            set { network = value; }
+        }
+
+        private string neighbor;
+
+        public string Neighbor
+        {
+            get { return neighbor; }
+            set { neighbor = value; }
+        }
+
+        private string interfaceID;
+
+        public string InterfaceID
+        {
+            get { return interfaceID; }
+            set { interfaceID = value; }
+        }
+
+        private string interfaceGone;
+
+        public string InterfaceGone
+        {
+            get { return interfaceGone; }
+            set { interfaceGone = value; }
+        }
+
+        private int remoteAS = -1;
+
+        public int RemoteAS
+        {
+            get { return remoteAS; }
+            set { remoteAS = value; }
+        }
+
+        private int area = -1;
+
+        public int Area
+        {
+            get { return area; }
+            set { area = value; }
+        }
+
+        private int process = -1;
+
+        public int Process
+        {
+            get { return process; }
+            set { process = value; }
+        }
+    }
+
     #endregion

     internal sealed partial class Probe
@@ -195,7 +270,7 @@

             #region VRF

-            Dictionary<string, PERouteNameToDatabase> routelive = new Dictionary<string, PERouteNameToDatabase>();
+            Dictionary<string, PERouteNameToDatabase> routenamelive = new Dictionary<string, PERouteNameToDatabase>();
             Dictionary<string, Row> routenamedb = QueryDictionary("select * from PERouteName where PN_NO = {0}", "PN_Name", nodeID);
             Dictionary<string, List<string>> routetargetlocaldb = new Dictionary<string, List<string>>();

@@ -268,7 +343,7 @@
                                 i.Name = name;
                                 i.RD = RD;
                                 i.RouteTargets = routeTargets.ToArray();
-                                routelive.Add(name, i);
+                                routenamelive.Add(name, i);
                                 name = null;
                                 routeTargets.Clear();
                             }
@@ -289,7 +364,7 @@
                         i.Name = name;
                         i.RD = RD;
                         i.RouteTargets = routeTargets.ToArray();
-                        routelive.Add(name, i);
+                        routenamelive.Add(name, i);
                     }

                     #endregion
@@ -313,7 +388,7 @@
                                 i.Name = name;
                                 i.RD = RD;
                                 i.RouteTargets = routeTargets.ToArray();
-                                routelive.Add(name, i);
+                                routenamelive.Add(name, i);
                             }

                             routeTargets.Clear();
@@ -348,7 +423,7 @@
                             i.Name = name;
                             i.RD = RD;
                             i.RouteTargets = routeTargets.ToArray();
-                            routelive.Add(name, i);
+                            routenamelive.Add(name, i);
                         }
                     }
                     #endregion
@@ -391,7 +466,7 @@
                             i.RDIPv6 = RDIPv6;
                             i.RouteTargets = routeTargets.ToArray();

-                            routelive.Add(name, i);
+                            routenamelive.Add(name, i);

                             name = null;
                             ipv = null;
@@ -440,7 +515,7 @@
                     i.RDIPv6 = RDIPv6;
                     i.RouteTargets = routeTargets.ToArray();

-                    routelive.Add(name, i);
+                    routenamelive.Add(name, i);
                 }

                 #endregion
@@ -450,7 +525,7 @@

             #region Check

-            foreach (KeyValuePair<string, PERouteNameToDatabase> pair in routelive)
+            foreach (KeyValuePair<string, PERouteNameToDatabase> pair in routenamelive)
             {
                 PERouteNameToDatabase li = pair.Value;
                 if (!routenamedb.ContainsKey(pair.Key))
@@ -466,6 +541,9 @@
                     if (routetargetlocaldb.ContainsKey(pair.Key)) routeTargets = routetargetlocaldb[pair.Key];

                     PERouteNameToDatabase u = new PERouteNameToDatabase();
+
+                    u.ID = db["PN_ID"].ToString();
+                    li.ID = u.ID;

                     bool update = false;
                     StringBuilder updateinfo = new StringBuilder();
@@ -502,7 +580,6 @@

                     if (update)
                     {
-                        u.ID = db["PN_ID"].ToString();
                         u.Name = pair.Key;
                         routenameupdate.Add(u);
                         Event("VRF Name UPDATE: " + pair.Key + " " + updateinfo.ToString());
@@ -510,7 +587,7 @@
                 }
             }

-            Summary("VRF_COUNT", routelive.Count);
+            Summary("VRF_COUNT", routenamelive.Count);

             // Search/set route targets
             List<PERouteNameToDatabase> routetargetsearch = new List<PERouteNameToDatabase>(routenameinsert);
@@ -2306,6 +2383,7 @@
             foreach (string id in interfacedelete)
             {
                 batch.Execute("update POP set OO_PI = NULL where OO_PI = {0}", id);
+                batch.Execute("update PERouteUse set PU_PI = NULL, PU_PI_Gone = (select PI_Name from PEInterface where PI_ID = {0}) where PU_PI = {0}", id);
                 batch.Execute("delete from PEInterface where PI_ID = {0}", id);
             }
             result = batch.Commit();
@@ -2342,6 +2420,631 @@
             }
             result = batch.Commit();
             Event(result, EventActions.Update, EventElements.POPInterfaceReference, false);
+
+            #endregion
+
+            #endregion
+
+            #region ROUTING
+
+            Dictionary<string, PERouteUseToDatabase> routeuselive = new Dictionary<string, PERouteUseToDatabase>();
+            Dictionary<string, Row> routeusedb = QueryDictionary("select PERouteUse.* from PERouteUse, PERouteName where PU_PN = PN_ID and PN_NO = {0}", delegate(Row row)
+            {
+                StringBuilder keysb = new StringBuilder();
+
+                keysb.Append(row["PU_PN"].ToString());
+                keysb.Append("_");
+
+                string type = row["PU_Type"].ToString();
+                keysb.Append(type);
+                keysb.Append("_");
+
+                if (type == "S")
+                {
+                    keysb.Append(row["PU_Network"].ToString());
+                    keysb.Append("_");
+                    keysb.Append(row["PU_Neighbor"].ToString(""));
+                    keysb.Append("_");
+                    string pi = row["PU_PI"].ToString();
+                    string piGone = row["PU_PI_Gone"].ToString();
+                    keysb.Append(pi != null ? pi : piGone != null ? piGone : "");
+                }
+                else if (type == "B")
+                {
+                    keysb.Append(row["PU_Neighbor"].ToString());
+                    keysb.Append("_");
+                    int remoteAS = row["PU_B_RemoteAS"].ToInt(-1);
+                    keysb.Append("" + (remoteAS != -1 ? remoteAS + "" : ""));
+                }
+                else if (type == "O")
+                {
+                    int process = row["PU_O_Process"].ToInt(-1);
+                    keysb.Append(process != -1 ? process + "_" : "_");
+                    int area = row["PU_O_Area"].ToInt(-1);
+                    keysb.Append(area != -1 ? area + "_" : "_");
+
+                }
+                else if (type == "R")
+                {
+                    string pi = row["PU_PI"].ToString();
+                    string piGone = row["PU_PI_Gone"].ToString();
+                    keysb.Append(pi != null ? pi : piGone != null ? piGone : "");
+                }
+                else if (type == "E")
+                {
+                    string pi = row["PU_PI"].ToString();
+                    string piGone = row["PU_PI_Gone"].ToString();
+                    keysb.Append(pi != null ? pi : piGone != null ? piGone : "");
+                }
+
+                return keysb.ToString();
+
+            }, nodeID);
+            List<PERouteUseToDatabase> routeuseinsert = new List<PERouteUseToDatabase>();
+
+            Event("Checking Routing");
+
+            #region Live
+
+            if (nodeManufacture == cso)
+            {
+                #region cso
+
+                if (nodeVersion == xr)
+                {
+                    #region xr
+
+                    string currentRouteNameID = null;
+                    string currentNeighbor = null;
+                    string currentRemoteAS = null;
+                    string currentProcess = null;
+                    string currentArea = null;
+                    string currentInterface = null;
+
+                    #region STATIC
+                    if (Request("sh run router static", out lines)) return;
+
+                    foreach (string line in lines)
+                    {
+                        string linetrim = line.Trim();
+                        if (linetrim.Length > 0)
+                        {
+                            if (linetrim.StartsWith("vrf "))
+                            {
+                                string vrfname = linetrim.Substring(4);
+
+                                if (routenamedb.ContainsKey(vrfname) && routenamelive.ContainsKey(vrfname))
+                                    currentRouteNameID = routenamedb[vrfname]["PN_ID"].ToString();
+                                else
+                                    currentRouteNameID = null;
+                            }
+                            else if (currentRouteNameID != null)
+                            {
+                                if (char.IsDigit(linetrim[0]))
+                                {
+                                    string[] parts = linetrim.Split(StringSplitTypes.Space, StringSplitOptions.RemoveEmptyEntries);
+
+                                    string network = null, neighbor = null, interfaceID = null;
+                                    string ifname = null;
+                                    if (parts.Length == 2)
+                                    {
+                                        network = parts[0];
+
+                                        if (char.IsDigit(parts[1][0]))
+                                            neighbor = parts[1];
+                                        else
+                                        {
+                                            // probably interface
+                                            NodeInterface nif = NodeInterface.Parse(parts[1]);
+                                            if (nif != null)
+                                            {
+                                                ifname = nif.GetShort();
+                                                if (interfacelive.ContainsKey(ifname))
+                                                {
+                                                    interfaceID = interfacelive[ifname].ID;
+                                                }
+                                            }
+
+                                            neighbor = "INTERFACE";
+                                        }
+                                    }
+                                    else if (parts.Length == 3)
+                                    {
+                                        network = parts[0];
+                                        NodeInterface nif = NodeInterface.Parse(parts[1]);
+                                        if (nif != null)
+                                        {
+                                            ifname = nif.GetShort();
+                                            if (interfacelive.ContainsKey(ifname))
+                                            {
+                                                interfaceID = interfacelive[ifname].ID;
+                                            }
+                                        }
+                                        neighbor = parts[2];
+                                    }
+
+                                    if (network != null)
+                                    {
+                                        PERouteUseToDatabase i = new PERouteUseToDatabase();
+                                        i.RouteNameID = currentRouteNameID;
+                                        i.Type = "S";
+                                        i.Network = network;
+                                        i.Neighbor = neighbor;
+                                        i.InterfaceID = interfaceID;
+
+                                        if (interfaceID == null && ifname != null)
+                                        {
+                                            i.InterfaceGone = ifname;
+                                        }
+
+                                        string key = currentRouteNameID + "_S_" + network + "_" + (neighbor != null ? neighbor : "") + "_" + (interfaceID != null ? interfaceID : ifname != null ? ifname : "");
+                                        routeuselive.Add(key, i);
+                                    }
+                                }
+                            }
+                        }
+                    }
+
+                    #endregion
+
+                    #region BGP
+                    if (Request("sh run router bgp", out lines)) return;
+
+                    currentRouteNameID = null;
+                    currentNeighbor = null;
+                    currentRemoteAS = null;
+
+                    foreach (string line in lines)
+                    {
+                        string linetrim = line.Trim();
+                        if (linetrim.Length > 0)
+                        {
+                            if (linetrim.StartsWith("vrf "))
+                            {
+                                string vrfname = linetrim.Substring(4);
+                                if (routenamedb.ContainsKey(vrfname) && routenamelive.ContainsKey(vrfname))
+                                    currentRouteNameID = routenamedb[vrfname]["PN_ID"].ToString();
+                                else
+                                    currentRouteNameID = null;
+
+                                currentNeighbor = null;
+                            }
+                            else if (currentRouteNameID != null)
+                            {
+                                if (linetrim.StartsWith("neighbor "))
+                                {
+                                    currentNeighbor = linetrim.Substring(9);
+                                    currentRemoteAS = null;
+                                }
+                                if (linetrim.StartsWith("remote-as "))
+                                {
+                                    currentRemoteAS = linetrim.Substring(10);
+                                }
+
+                                if (linetrim == "!")
+                                {
+                                    if (currentNeighbor != null)
+                                    {
+                                        PERouteUseToDatabase i = new PERouteUseToDatabase();
+                                        i.RouteNameID = currentRouteNameID;
+                                        i.Type = "B";
+                                        i.Neighbor = currentNeighbor;
+
+                                        if (currentRemoteAS != null)
+                                        {
+                                            int ras = -1;
+                                            if (int.TryParse(currentRemoteAS, out ras)) i.RemoteAS = ras;
+                                        }
+
+                                        string key = currentRouteNameID + "_B_" + currentNeighbor + "_" + (i.RemoteAS != -1 ? i.RemoteAS + "" : "");
+                                        routeuselive.Add(key, i);
+                                    }
+
+                                    currentNeighbor = null;
+                                    currentRemoteAS = null;
+                                }
+                            }
+                        }
+                    }
+
+                    #endregion
+
+                    #region OSPF
+                    if (Request("sh run router ospf", out lines)) return;
+
+                    currentRouteNameID = null;
+                    currentProcess = null;
+                    currentArea = null;
+                    currentInterface = null;
+                    currentNeighbor = null;
+
+                    foreach (string line in lines)
+                    {
+                        string linetrim = line.Trim();
+                        if (linetrim.Length > 0)
+                        {
+                            if (linetrim.StartsWith("router ospf "))
+                            {
+                                currentProcess = linetrim.Substring(12);
+
+                                currentRouteNameID = null;
+                                currentArea = null;
+                            }
+                            else if (currentProcess != null)
+                            {
+                                if (linetrim.StartsWith("vrf "))
+                                {
+                                    string vrfname = linetrim.Substring(4);
+                                    if (routenamedb.ContainsKey(vrfname) && routenamelive.ContainsKey(vrfname))
+                                        currentRouteNameID = routenamedb[vrfname]["PN_ID"].ToString();
+                                    else
+                                        currentRouteNameID = null;
+
+                                    currentArea = null;
+                                }
+                                else if (currentRouteNameID != null)
+                                {
+                                    if (linetrim.StartsWith("area "))
+                                    {
+                                        currentArea = linetrim.Substring(5);
+                                    }
+                                    else if (currentArea != null)
+                                    {
+                                        if (linetrim.StartsWith("interface "))
+                                        {
+                                            NodeInterface nif = NodeInterface.Parse(linetrim.Substring(10));
+                                            if (nif != null) currentInterface = nif.GetShort();
+
+                                            currentNeighbor = null;
+                                        }
+                                        else if (currentInterface != null)
+                                        {
+                                            if (linetrim.StartsWith("neighbor "))
+                                            {
+                                                currentNeighbor = linetrim.Substring(9);
+                                            }
+                                            else if (linetrim == "!")
+                                            {
+                                                PERouteUseToDatabase i = new PERouteUseToDatabase();
+                                                i.RouteNameID = currentRouteNameID;
+                                                i.Type = "O";
+                                                i.Neighbor = currentNeighbor;
+
+                                                int oprocess, oarea;
+                                                if (int.TryParse(currentProcess, out oprocess)) i.Process = oprocess;
+                                                if (int.TryParse(currentArea, out oarea)) i.Area = oarea;
+
+                                                int par;
+                                                if (int.TryParse(currentArea, out par)) i.Area = par;
+
+                                                string interfaceID = null;
+                                                if (interfacelive.ContainsKey(currentInterface))
+                                                {
+                                                    interfaceID = interfacelive[currentInterface].ID;
+                                                    if (interfaceID != null)
+                                                    {
+                                                        i.InterfaceID = interfaceID;
+                                                    }
+                                                }
+                                                else if (currentInterface != null)
+                                                    i.InterfaceGone = currentInterface;
+
+                                                string key = currentRouteNameID + "_O_" + currentProcess + "_" + currentArea + "_" + (interfaceID != null ? interfaceID : currentInterface != null ? currentInterface : "");
+                                                routeuselive.Add(key, i);
+
+                                                currentInterface = null;
+                                                currentNeighbor = null;
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+
+                    #endregion
+
+                    #region RIP
+                    if (Request("sh run router rip", out lines)) return;
+
+                    currentRouteNameID = null;
+                    currentInterface = null;
+
+                    foreach (string line in lines)
+                    {
+                        string linetrim = line.Trim();
+                        if (linetrim.Length > 0)
+                        {
+                            if (linetrim.StartsWith("vrf "))
+                            {
+                                string vrfname = linetrim.Substring(4);
+                                if (routenamedb.ContainsKey(vrfname) && routenamelive.ContainsKey(vrfname))
+                                    currentRouteNameID = routenamedb[vrfname]["PN_ID"].ToString();
+                                else
+                                    currentRouteNameID = null;
+
+                                currentInterface = null;
+                            }
+                            else if (currentRouteNameID != null)
+                            {
+                                if (linetrim.StartsWith("interface "))
+                                {
+                                    NodeInterface nif = NodeInterface.Parse(linetrim.Substring(10));
+                                    if (nif != null) currentInterface = nif.GetShort();
+                                }
+                                else if (currentInterface != null)
+                                {
+                                    if (linetrim == "!")
+                                    {
+                                        PERouteUseToDatabase i = new PERouteUseToDatabase();
+                                        i.RouteNameID = currentRouteNameID;
+                                        i.Type = "R";
+
+                                        string interfaceID = null;
+                                        if (interfacelive.ContainsKey(currentInterface))
+                                        {
+                                            interfaceID = interfacelive[currentInterface].ID;
+                                            if (interfaceID != null)
+                                            {
+                                                i.InterfaceID = interfaceID;
+                                            }
+                                        }
+                                        else if (currentInterface != null)
+                                            i.InterfaceGone = currentInterface;
+
+                                        string key = currentRouteNameID + "_R_" + (interfaceID != null ? interfaceID : currentInterface != null ? currentInterface : "");
+                                        routeuselive.Add(key, i);
+
+                                        currentInterface = null;
+                                    }
+                                }
+                            }
+                        }
+                    }
+
+
+                    #endregion
+
+                    #region EIGRP
+                    if (Request("sh run router eigrp", out lines)) return;
+
+                    currentRouteNameID = null;
+                    currentInterface = null;
+
+                    foreach (string line in lines)
+                    {
+                        string linetrim = line.Trim();
+                        if (linetrim.Length > 0)
+                        {
+                            if (linetrim.StartsWith("vrf "))
+                            {
+                                string vrfname = linetrim.Substring(4);
+                                if (routenamedb.ContainsKey(vrfname) && routenamelive.ContainsKey(vrfname))
+                                    currentRouteNameID = routenamedb[vrfname]["PN_ID"].ToString();
+                                else
+                                    currentRouteNameID = null;
+
+                                currentInterface = null;
+                            }
+                            else if (currentRouteNameID != null)
+                            {
+                                if (linetrim.StartsWith("interface "))
+                                {
+                                    NodeInterface nif = NodeInterface.Parse(linetrim.Substring(10));
+                                    if (nif != null) currentInterface = nif.GetShort();
+                                }
+                                else if (currentInterface != null)
+                                {
+                                    if (linetrim == "!")
+                                    {
+                                        PERouteUseToDatabase i = new PERouteUseToDatabase();
+                                        i.RouteNameID = currentRouteNameID;
+                                        i.Type = "E";
+
+                                        string interfaceID = null;
+                                        if (interfacelive.ContainsKey(currentInterface))
+                                        {
+                                            interfaceID = interfacelive[currentInterface].ID;
+                                            if (interfaceID != null)
+                                            {
+                                                i.InterfaceID = interfaceID;
+                                            }
+                                        }
+                                        else if (currentInterface != null)
+                                            i.InterfaceGone = currentInterface;
+
+                                        string key = currentRouteNameID + "_E_" + (interfaceID != null ? interfaceID : currentInterface != null ? currentInterface : "");
+                                        routeuselive.Add(key, i);
+
+                                        currentInterface = null;
+                                    }
+                                }
+                            }
+                        }
+                    }
+
+                    #endregion
+
+                    #endregion
+                }
+
+                #endregion
+            }
+
+            #endregion
+
+            #region Check
+
+            foreach (KeyValuePair<string, PERouteUseToDatabase> pair in routeuselive)
+            {
+                PERouteUseToDatabase li = pair.Value;
+
+                if (!routeusedb.ContainsKey(pair.Key))
+                {
+                    string info = "UNKNOWN ";
+                    foreach (KeyValuePair<string, Row> pair2 in routenamedb)
+                    {
+                        if (pair2.Value["PN_ID"].ToString() == li.RouteNameID)
+                        {
+                            info = pair2.Key + " ";
+                            break;
+                        }
+                    }
+
+                    string referencedinterface = null;
+
+                    if (li.InterfaceID != null)
+                    {
+                        foreach (KeyValuePair<string, PEInterfaceToDatabase> pair2 in interfacelive)
+                        {
+                            if (pair2.Value.ID == li.InterfaceID)
+                            {
+                                referencedinterface = pair2.Key;
+                                break;
+                            }
+                        }
+                    }
+                    else
+                        referencedinterface = li.InterfaceGone + " NOTEXISTS";
+
+                    if (li.Type == "S") info += "static " + li.Network + " to " + li.Neighbor + (referencedinterface != null ? " (" + referencedinterface + ")" : "");
+                    else if (li.Type == "B") info += "bgp to " + li.Neighbor + " by remote AS " + li.RemoteAS;
+                    else if (li.Type == "O") info += "ospf area " + li.Area + (referencedinterface != null ? " (" + referencedinterface + ")" : "");
+                    else if (li.Type == "R") info += "rip" + (referencedinterface != null ? " (" + referencedinterface + ")" : "");
+                    else if (li.Type == "E") info += "eigrp" + (referencedinterface != null ? " (" + referencedinterface + ")" : "");
+
+                    Event("Routing ADD: " + info);
+
+                    li.ID = Database.ID();
+                    routeuseinsert.Add(li);
+                }
+                else
+                {
+                    Row db = routeusedb[pair.Key];
+
+                    PERouteUseToDatabase u = new PERouteUseToDatabase();
+                    u.ID = db["PU_ID"].ToString();
+                    li.ID = u.ID;
+
+                    bool update = false;
+                    StringBuilder updateinfo = new StringBuilder();
+
+                    if (li.Type == "S")
+                    {
+
+                    }
+                    else if (li.Type == "B")
+                    {
+
+                    }
+                    else if (li.Type == "O")
+                    {
+
+                    }
+                    else if (li.Type == "R")
+                    {
+
+                    }
+                    else if (li.Type == "E")
+                    {
+
+                    }
+                }
+            }
+
+            #endregion
+
+            #region Execute
+
+            // ADD
+            batch.Begin();
+            foreach (PERouteUseToDatabase s in routeuseinsert)
+            {
+                Insert insert = Insert("PERouteUse");
+                insert.Value("PU_ID", s.ID);
+                insert.Value("PU_PN", s.RouteNameID);
+                insert.Value("PU_Type", s.Type);
+
+                insert.Value("PU_PI", s.InterfaceID);
+                insert.Value("PU_PI_Gone", s.InterfaceGone);
+                insert.Value("PU_Network", s.Network);
+                insert.Value("PU_Neighbor", s.Neighbor);
+
+                if (s.Type == "S")
+                {
+
+                }
+                else if (s.Type == "B")
+                {
+                    insert.Value("PU_B_RemoteAS", s.RemoteAS);
+                }
+                else if (s.Type == "O")
+                {
+                    insert.Value("PU_O_Process", s.Process);
+                    insert.Value("PU_O_Area", s.Area);
+                }
+                else if (s.Type == "R")
+                {
+
+                }
+                else if (s.Type == "E")
+                {
+
+                }
+
+                batch.Execute(insert);
+            }
+            result = batch.Commit();
+            Event(result, EventActions.Add, EventElements.Routing, false);
+
+            // DELETE
+            batch.Begin();
+            foreach (KeyValuePair<string, Row> pair in routeusedb)
+            {
+                if (!routeuselive.ContainsKey(pair.Key))
+                {
+                    string info = "UNKNOWN ";
+                    foreach (KeyValuePair<string, Row> pair2 in routenamedb)
+                    {
+                        if (pair2.Value["PN_ID"].ToString() == pair.Value["PU_PN"].ToString())
+                        {
+                            info = pair2.Key + " ";
+                            break;
+                        }
+                    }
+
+                    string referencedinterface = null;
+                    string interfaceID = pair.Value["PU_PI"].ToString();
+                    string interfaceGone = pair.Value["PU_PI_Gone"].ToString();
+
+                    if (interfaceID != null)
+                    {
+                        foreach (KeyValuePair<string, PEInterfaceToDatabase> pair2 in interfacelive)
+                        {
+                            if (pair2.Value.ID == interfaceID)
+                            {
+                                referencedinterface = pair2.Key;
+                                break;
+                            }
+                        }
+                    }
+                    else if (interfaceGone != null)
+                        referencedinterface = interfaceGone + " NOTEXISTS";
+
+                    string type = pair.Value["PU_Type"].ToString();
+
+                    if (type == "S") info += "static " + pair.Value["PU_Network"].ToString() + " to " + pair.Value["PU_Neighbor"].ToString() + (referencedinterface != null ? " (" + referencedinterface + ")" : "");
+                    else if (type == "B") info += "bgp to " + pair.Value["PU_Neighbor"].ToString() + " by remote AS " + pair.Value["PU_B_RemoteAS"].ToString();
+                    else if (type == "O") info += "ospf area " + pair.Value["PU_O_Area"].ToString() + (referencedinterface != null ? " (" + referencedinterface + ")" : "");
+                    else if (type == "R") info += "rip" + (referencedinterface != null ? " (" + referencedinterface + ")" : "");
+                    else if (type == "E") info += "eigrp" + (referencedinterface != null ? " (" + referencedinterface + ")" : "");
+
+                    Event("Routing DELETE: " + info);
+                    batch.Execute("delete from PERouteUse where PU_ID = {0}", pair.Value["PU_ID"].ToString());
+                }
+            }
+            result = batch.Commit();
+            Event(result, EventActions.Delete, EventElements.Routing, false);

             #endregion

@@ -2367,11 +3070,12 @@
             List<string> routenamedelete = new List<string>();
             foreach (KeyValuePair<string, Row> pair in routenamedb)
             {
-                if (!routelive.ContainsKey(pair.Key))
+                if (!routenamelive.ContainsKey(pair.Key))
                 {
                     Event("Route Name DELETE: " + pair.Key);
                     string id = pair.Value["PN_ID"].ToString();
                     batch.Execute("update PEInterface set PI_PN = NULL where PI_PN = {0}", id);
+                    batch.Execute("delete from PERouteUse where PU_PN = {0}", id);
                     routenamedelete.Add(id);
                 }
             }