public static bool IsValidGasConnection(MyCubeBlock factoryBlock, IMySlimBlock gasTankBlock, out IMyGasTank gasTank)
        {
            gasTank = null;

            try
            {
                if (gasTankBlock.FatBlock == null || gasTankBlock.FatBlock as IMyGasTank == null)
                {
                    return(false);
                }

                gasTank = gasTankBlock.FatBlock as IMyGasTank;

                if (gasTank.GetInventory() == null ||
                    !((IMyInventory)factoryBlock.GetInventory()).IsConnectedTo(gasTank.GetInventory()) ||
                    !MyRelationsBetweenPlayerAndBlockExtensions.IsFriendly(factoryBlock.GetUserRelationToOwner(gasTank.OwnerId)))
                {
                    return(false);
                }

                return(true);
            }
            catch (Exception e)
            {
                Logging.Instance.WriteLine($"IsValidGasConnection exception:\n{e}.");
                return(false);
            }
        }
        public static bool IsValidInventoryConnection(object FactoryBlockInv, object TargetBlockInv, out IMyInventory inv)
        {
            inv = null;
            try
            {
                MyInventory FactoryInv = (MyInventory)FactoryBlockInv;
                MyEntity    TargetInv  = null;

                if (TargetBlockInv is IMySlimBlock && ((IMySlimBlock)TargetBlockInv).FatBlock != null)
                {
                    TargetInv = (MyEntity)((IMyEntity)(((IMySlimBlock)TargetBlockInv).FatBlock));
                }

                else if (TargetBlockInv is MyInventory || TargetBlockInv is IMyInventory)
                {
                    TargetInv = ((MyInventory)TargetBlockInv).Owner;
                }

                MyCubeBlock FactoryInvBlock = (MyCubeBlock)FactoryInv.Owner;
                if (TargetInv == null || FactoryInv == null || FactoryInvBlock == null || !TargetInv.HasInventory)
                {
                    return(false);
                }

                MyCubeBlock InvBlock = TargetInv as MyCubeBlock;
                if (InvBlock == null)
                {
                    return(false);
                }

                IMyProductionBlock prodblock = TargetInv as IMyProductionBlock; //assembler
                inv = (prodblock != null && prodblock.OutputInventory != null) ? prodblock.OutputInventory : ((IMyEntity)TargetInv).GetInventory();

                if (inv == null || !InvBlock.IsFunctional || NaniteConstructionManager.NaniteBlocks.ContainsKey(TargetInv.EntityId) ||
                    TargetInv is Sandbox.ModAPI.Ingame.IMyReactor || !inv.IsConnectedTo((IMyInventory)FactoryInv) ||
                    !MyRelationsBetweenPlayerAndBlockExtensions.IsFriendly(FactoryInvBlock.GetUserRelationToOwner(InvBlock.OwnerId)))
                {
                    return(false);
                }

                return(true);
            }
            catch (Exception e)
            {
                Logging.Instance.WriteLine($"IsValidInventoryConnection exception:\n{e}.");
                return(false);
            }
        }
        public override void ParallelUpdate(List <IMyCubeGrid> NaniteGridGroup, List <BlockTarget> gridBlocks)
        {
            try
            {
                // Add
                foreach (var beaconBlock in NaniteConstructionManager.BeaconList.Where(x => x.Value is NaniteBeaconDeconstruct))
                {
                    IMyCubeBlock item = (IMyCubeBlock)beaconBlock.Value.BeaconBlock;

                    if (item == null ||
                        item.CubeGrid == null ||
                        !((IMyFunctionalBlock)item).Enabled ||
                        !((IMyFunctionalBlock)item).IsFunctional ||
                        NaniteGridGroup.Contains(item.CubeGrid) ||
                        !MyRelationsBetweenPlayerAndBlockExtensions.IsFriendly(item.GetUserRelationToOwner(m_constructionBlock.ConstructionBlock.OwnerId)) ||
                        m_validBeaconedGrids.FirstOrDefault(x => x.GridsProcessed.Contains(item.CubeGrid)) != null ||
                        !IsInRange(item.GetPosition(), m_maxDistance)
                        )
                    {
                        continue;
                    }

                    NaniteDeconstructionGrid deconstruct = new NaniteDeconstructionGrid(item.CubeGrid);

                    CreateGridStack(NaniteGridGroup, deconstruct, (MyCubeGrid)item.CubeGrid, (MyCubeBlock)item);
                    m_validBeaconedGrids.Add(deconstruct);

                    Logging.Instance.WriteLine($"[Deconstruction] Grid {item.CubeGrid.CustomName} queued for deconstruction", 1);

                    foreach (var slimBlock in deconstruct.RemoveList)
                    {
                        if (slimBlock != null)
                        {
                            PotentialTargetList.Add(slimBlock);
                        }
                    }

                    deconstruct.RemoveList.Clear();
                }

                CheckAreaBeacons(NaniteGridGroup);

                if (PotentialTargetList.Count > 0)
                {
                    foreach (IMySlimBlock item in PotentialTargetList.ToList())
                    {
                        if (item == null || item.CubeGrid == null || item.CubeGrid.Closed || item.IsDestroyed || item.IsFullyDismounted ||
                            (item.FatBlock != null && item.FatBlock.Closed) ||
                            EntityHelper.GetDistanceBetweenBlockAndSlimblock((IMyCubeBlock)m_constructionBlock.ConstructionBlock, item) > m_maxDistance)
                        {
                            PotentialTargetList.Remove(item);
                        }
                    }
                }
                else if (TargetList.Count == 0 && PotentialTargetList.Count == 0)
                {
                    m_validBeaconedGrids.Clear();
                }
            }
            catch (Exception e)
            { Logging.Instance.WriteLine($"Exception in NaniteDeconstructionTargets.ParallelUpdate:\n{e}"); }
        }