private bool PasteInternal(MyInventoryBase buildInventory, bool missingDefinitions, bool deactivate, List<MyObjectBuilder_CubeGrid> pastedBuilders = null, List<MyCubeGrid> touchingGrids = null,
            UpdateAfterPasteCallback updateAfterPasteCallback = null, bool multiBlock = false)
        {
            var copiedLocalGrids = new List<MyObjectBuilder_CubeGrid>();
            foreach (var gridCopy in m_copiedGrids)
            {
                copiedLocalGrids.Add((MyObjectBuilder_CubeGrid)gridCopy.Clone());
            }

            var grid = copiedLocalGrids[0];
            bool isMergeNeeded = IsSnapped && SnapMode == SnapMode.Base6Directions && m_hitEntity is MyCubeGrid && grid != null && ((MyCubeGrid)m_hitEntity).GridSizeEnum == grid.GridSizeEnum;

            if (isMergeNeeded && !IsMergeWithinWorldLimits())
            {
                MyGuiAudio.PlaySound(MyGuiSounds.HudUnable);
                MyHud.Notifications.Add(MyNotificationSingletons.ShipOverLimits);
                return false;
            }

            MyGuiAudio.PlaySound(MyGuiSounds.HudPlaceBlock);

            MyCubeGrid hitGrid = null;
            if(isMergeNeeded)
            {
                hitGrid = m_hitEntity as MyCubeGrid;
            }

            isMergeNeeded |= touchingGrids != null && touchingGrids.Count > 0;

            if(hitGrid == null && touchingGrids != null && touchingGrids.Count > 0)
            {
                hitGrid = touchingGrids[0];
            }

            int i = 0;
            foreach (var gridBuilder in copiedLocalGrids)
            {
                gridBuilder.CreatePhysics = true;
                gridBuilder.EnableSmallToLargeConnections = true;

                gridBuilder.PositionAndOrientation = new MyPositionAndOrientation(m_previewGrids[i].WorldMatrix);
                gridBuilder.PositionAndOrientation.Value.Orientation.Normalize();
                i++;
            }

            long inventoryOwnerId = 0;

            if (buildInventory != null)
            {
                if (MyFakes.ENABLE_MEDIEVAL_INVENTORY)
                {
                    inventoryOwnerId = buildInventory.Entity.EntityId;
                }
                else if( buildInventory is MyInventory)
                {
                    inventoryOwnerId = (buildInventory as MyInventory).Owner.EntityId;
                }
            }

            bool isAdmin = MySession.Static.IsAdminModeEnabled(Sync.MyId);

            if (isMergeNeeded && hitGrid != null)
            {
                hitGrid.PasteBlocksToGrid(copiedLocalGrids, inventoryOwnerId, multiBlock, isAdmin);
            }
            //TODO: GZA - This is connected with creational clipboards used to create new grids in space. Should be removed later.
            else if(CreationMode)
            {
                MyMultiplayer.RaiseStaticEvent(s => MyCubeGrid.TryCreateGrid_Implementation, CubeSize, IsStatic, copiedLocalGrids[0].PositionAndOrientation.Value, inventoryOwnerId, isAdmin);
                CreationMode = false;
            }
            else if (MySession.Static.CreativeMode || MySession.Static.HasAdminRights)
            {
                bool anyGridInGround = false;
                bool anyGridIsSmall = false;

                foreach (var prevGrid in m_previewGrids)
                {
                    anyGridIsSmall |= prevGrid.GridSizeEnum == MyCubeSize.Small;

                    var settings = m_settings.GetGridPlacementSettings(prevGrid.GridSizeEnum, prevGrid.IsStatic);
                    anyGridInGround |= MyCubeGrid.IsAabbInsideVoxel(prevGrid.PositionComp.WorldMatrix, (BoundingBoxD)prevGrid.PositionComp.LocalAABB, settings);
                }

                bool smallInMedieval = false;
                if (MyPerGameSettings.Game == GameEnum.ME_GAME)
                {
                    MyCubeGrid hitEntGrid = m_hitEntity as MyCubeGrid;
                    if (hitEntGrid != null)
                        smallInMedieval = anyGridIsSmall && (hitEntGrid.GridSizeEnum == MyCubeSize.Large);
                }

                foreach (var gridOb in copiedLocalGrids)
                {
                    gridOb.IsStatic = smallInMedieval || anyGridInGround || (MySession.Static.EnableConvertToStation && gridOb.IsStatic);                    
                }
                if (!MySandboxGame.IsDedicated)
                {
                    MyHud.PushRotatingWheelVisible();
                }
                MyMultiplayer.RaiseStaticEvent(s => MyCubeGrid.TryPasteGrid_Implementation, copiedLocalGrids, missingDefinitions, inventoryOwnerId, m_objectVelocity, multiBlock, isAdmin);
            }

            if (deactivate)
            {
                Deactivate(afterPaste: true);
            }

            if (updateAfterPasteCallback != null)
            {
                updateAfterPasteCallback(pastedBuilders);
            }
           
            return true;
        }
        protected bool PasteGridInternal(MyInventoryBase buildInventory, bool deactivate, List<MyObjectBuilder_CubeGrid> pastedBuilders = null, List<MyCubeGrid> touchingGrids = null,
            UpdateAfterPasteCallback updateAfterPasteCallback = null, bool multiBlock = false)
        {
            if (m_copiedGrids.Count == 0)
                return false;

            if ((m_copiedGrids.Count > 0) && !IsActive)
            {
                Activate();
                return true;
            }

            if (!CanBePlaced)
            {
                MyGuiAudio.PlaySound(MyGuiSounds.HudUnable);
                return false;
            }

            if (!IsWithinWorldLimits())
            {
                MyGuiAudio.PlaySound(MyGuiSounds.HudUnable);
                MyHud.Notifications.Add(MyNotificationSingletons.ShipOverLimits);
                return false;
            }

            if (m_previewGrids.Count == 0)
                return false;

            foreach (var grid in m_copiedGrids)
            {
                foreach (var block in grid.CubeBlocks)
                {
                    block.BuiltBy = MySession.Static.LocalPlayerId;
                }
            }

            bool missingBlockDefinitions = false;
            if (ShowModdedBlocksWarning)
            {
                missingBlockDefinitions = !CheckPastedBlocks();
            }

            if (missingBlockDefinitions)
            {
                AllowSwitchCameraMode = false;
                var messageBox = MyGuiSandbox.CreateMessageBox(
                    styleEnum: MyMessageBoxStyleEnum.Info,
                    buttonType: MyMessageBoxButtonsType.YES_NO,
                    messageText: MyTexts.Get(MyCommonTexts.MessageBoxTextDoYouWantToPasteGridWithMissingBlocks),
                    messageCaption: MyTexts.Get(MyCommonTexts.MessageBoxCaptionWarning),
                    callback: (result) =>
                    {
                        if (result == MyGuiScreenMessageBox.ResultEnum.YES)
                        {
                            PasteInternal(buildInventory, missingBlockDefinitions, deactivate, pastedBuilders, updateAfterPasteCallback: updateAfterPasteCallback, multiBlock: multiBlock);
                        }
                        AllowSwitchCameraMode = true;
                    });
                MyGuiSandbox.AddScreen(messageBox);
                return false;
            }

            return PasteInternal(buildInventory, missingBlockDefinitions, deactivate, pastedBuilders: pastedBuilders, touchingGrids: touchingGrids, 
                updateAfterPasteCallback: updateAfterPasteCallback, multiBlock: multiBlock);
        }
        private bool PasteInternal(MyInventoryBase buildInventory, bool missingDefinitions, bool deactivate, List<MyObjectBuilder_CubeGrid> pastedBuilders = null, List<MyCubeGrid> touchingGrids = null,
            UpdateAfterPasteCallback updateAfterPasteCallback = null)
        {
            MyGuiAudio.PlaySound(MyGuiSounds.HudPlaceBlock);

            MyEntities.RemapObjectBuilderCollection(m_copiedGrids);

            m_tmpPastedBuilders.Clear();
            m_tmpPastedBuilders.Capacity = m_copiedGrids.Count;
            MyCubeGrid firstPastedGrid = null;

            bool forceDynamicGrid = IsForcedDynamic() && !m_gridChangeToDynamicDisabled;

            int i = 0;
            bool retVal = false;
            List<MyCubeGrid> pastedGrids = new List<MyCubeGrid>();

            foreach (var gridBuilder in m_copiedGrids)
               {
                gridBuilder.CreatePhysics = true;
                gridBuilder.EnableSmallToLargeConnections = true;
                bool savedStaticFlag = gridBuilder.IsStatic;

                if (forceDynamicGrid)
                {
                    gridBuilder.IsStatic = false;
                }

                var previousPos = gridBuilder.PositionAndOrientation;
                gridBuilder.PositionAndOrientation = new MyPositionAndOrientation(m_previewGrids[i].WorldMatrix);

                var pastedGrid = MyEntities.CreateFromObjectBuilder(gridBuilder) as MyCubeGrid;

                if (pastedGrid == null)
                {
                    retVal = true;
                    continue;
                }

                if (MySession.Static.EnableStationVoxelSupport && pastedGrid.IsStatic)
                {
                    pastedGrid.TestDynamic = true;
                }

                //pastedGrid.PositionComp.SetPosition(MySector.MainCamera.Position);
                MyEntities.Add(pastedGrid);
                if (i == 0) firstPastedGrid = pastedGrid;

               
                if (missingDefinitions)
                    pastedGrid.DetectDisconnectsAfterFrame();

                //pastedGrid.PositionComp.SetWorldMatrix(m_previewGrids[i].WorldMatrix);
                i++;

                if (!pastedGrid.IsStatic && (!MyFakes.ENABLE_BATTLE_SYSTEM || !MySession.Static.Battle))
                    pastedGrid.Physics.LinearVelocity = m_objectVelocity;

                if (!pastedGrid.IsStatic && MySession.ControlledEntity != null && MySession.ControlledEntity.Entity.Physics != null && m_calculateVelocity
                    && (!MyFakes.ENABLE_BATTLE_SYSTEM || !MySession.Static.Battle))
                {
                    pastedGrid.Physics.AngularVelocity = MySession.ControlledEntity.Entity.Physics.AngularVelocity;
                }

                pastedGrids.Add(pastedGrid);

                gridBuilder.IsStatic = savedStaticFlag;

                retVal = true;
            }

            //Because blocks fills SubBlocks in this method..
            //TODO: Create LoadPhase2
            MyEntities.UpdateOnceBeforeFrame();

            foreach (var pastedGrid in pastedGrids)
            {
                var builder = pastedGrid.GetObjectBuilder();
                m_tmpPastedBuilders.Add(builder);

                if (pastedBuilders != null)
                    pastedBuilders.Add((MyObjectBuilder_CubeGrid)builder);
            }

            if (IsSnapped && SnapMode == MyGridPlacementSettings.SnapMode.Base6Directions && m_hitEntity is MyCubeGrid && firstPastedGrid != null && ((MyCubeGrid)m_hitEntity).GridSizeEnum == firstPastedGrid.GridSizeEnum)
            {
                var hitGrid = m_hitEntity as MyCubeGrid;

                MatrixI mergingTransform = hitGrid.CalculateMergeTransform(firstPastedGrid, hitGrid.WorldToGridInteger(firstPastedGrid.PositionComp.GetPosition()));
                MySyncCreate.RequestMergingCopyPaste(m_tmpPastedBuilders, m_hitEntity.EntityId, mergingTransform);
            }
            else if (touchingGrids != null && touchingGrids.Count > 0)
            {
                // Currently only first grid is supported for merging.
                MyCubeGrid touchingGrid = touchingGrids[0];

                if (touchingGrid != null)
                {
                    MatrixI mergingTransform = touchingGrid.CalculateMergeTransform(firstPastedGrid, touchingGrid.WorldToGridInteger(firstPastedGrid.PositionComp.GetPosition()));
                    MySyncCreate.RequestMergingCopyPaste(m_tmpPastedBuilders, touchingGrid.EntityId, mergingTransform);
                }
                else
                {
                    //MySyncCreate.RequestEntitiesCreate(m_tmpPastedBuilders);
                    MySyncCreate.SendEntitiesCreated(m_tmpPastedBuilders);
                }
            }
            else
            {
                // CH:TODO: This would probably be safer if it was requested from the server as well
                MySyncCreate.SendEntitiesCreated(m_tmpPastedBuilders);
            }

            // CH:TODO: Use only items for grids that were really added to not screw with players
            if (buildInventory != null)
            {
                foreach (var item in m_buildComponents.TotalMaterials)
                {
                    buildInventory.RemoveItemsOfType(item.Value, item.Key);
                }
            }

            if (deactivate)
                Deactivate();

            if (retVal && updateAfterPasteCallback != null)
            {
                updateAfterPasteCallback(pastedBuilders);
            }

            return retVal;
        }
        protected bool PasteGridInternal(MyInventoryBase buildInventory, bool deactivate, List<MyObjectBuilder_CubeGrid> pastedBuilders = null, List<MyCubeGrid> touchingGrids = null,
            UpdateAfterPasteCallback updateAfterPasteCallback = null)
        {
            if (m_copiedGrids.Count == 0)
                return false;

            if ((m_copiedGrids.Count > 0) && !IsActive)
            {
                Activate();
                return true;
            }

            if (!CanBePlaced)
            {
                MyGuiAudio.PlaySound(MyGuiSounds.HudUnable);
                return false;
            }

            if (m_previewGrids.Count == 0)
                return false;

            bool missingBlockDefinitions = !CheckPastedBlocks();

            if (missingBlockDefinitions)
            {
                AllowSwitchCameraMode = false;
                var messageBox = MyGuiSandbox.CreateMessageBox(
                    buttonType: MyMessageBoxButtonsType.YES_NO,
                    messageText: MyTexts.Get(MySpaceTexts.MessageBoxTextDoYouWantToPasteGridWithMissingBlocks),
                    messageCaption: MyTexts.Get(MySpaceTexts.MessageBoxCaptionWarning),
                    callback: (result) =>
                    {
                        if (result == MyGuiScreenMessageBox.ResultEnum.YES)
                        {
                            PasteInternal(buildInventory, missingBlockDefinitions, deactivate, pastedBuilders, updateAfterPasteCallback: updateAfterPasteCallback);
                        }
                        AllowSwitchCameraMode = true;
                    });
                MyGuiSandbox.AddScreen(messageBox);
                return false;
            }

            return PasteInternal(buildInventory, missingBlockDefinitions, deactivate, pastedBuilders: pastedBuilders, touchingGrids: touchingGrids, updateAfterPasteCallback: updateAfterPasteCallback);
        }
        private bool PasteInternal(MyInventoryBase buildInventory, bool missingDefinitions, bool deactivate, List<MyObjectBuilder_CubeGrid> pastedBuilders = null, List<MyCubeGrid> touchingGrids = null,
            UpdateAfterPasteCallback updateAfterPasteCallback = null)
        {
            MyGuiAudio.PlaySound(MyGuiSounds.HudPlaceBlock);

            var grid = m_copiedGrids[0];
            bool isMergeNeeded = IsSnapped && SnapMode == MyGridPlacementSettings.SnapMode.Base6Directions && m_hitEntity is MyCubeGrid && grid != null && ((MyCubeGrid)m_hitEntity).GridSizeEnum == grid.GridSizeEnum;
           
            MyCubeGrid hitGrid = null;
            if(isMergeNeeded)
            {
                hitGrid = m_hitEntity as MyCubeGrid;
            }

            isMergeNeeded |= touchingGrids != null && touchingGrids.Count > 0;

            if(touchingGrids != null && touchingGrids.Count > 0)
            {
                hitGrid = touchingGrids[0];
            }

            long hitEntityId = hitGrid != null ? hitGrid.EntityId : 0;

            bool forceDynamicGrid = IsForcedDynamic() && !m_gridChangeToDynamicDisabled;

            int i = 0;
            foreach (var gridBuilder in m_copiedGrids)
            {
                gridBuilder.CreatePhysics = true;
                gridBuilder.EnableSmallToLargeConnections = true;
                bool savedStaticFlag = gridBuilder.IsStatic;

                if (forceDynamicGrid)
                {
                    gridBuilder.IsStatic = false;
                }

                gridBuilder.PositionAndOrientation = new MyPositionAndOrientation(m_previewGrids[i].WorldMatrix);
                i++;
            }

            long inventoryOwnerId = 0;

            if (buildInventory != null)
            {
                if (MyFakes.ENABLE_MEDIEVAL_INVENTORY)
                {
                    inventoryOwnerId = buildInventory.Entity.EntityId;
                }
                else if( buildInventory is MyInventory)
                {
                    inventoryOwnerId = (buildInventory as MyInventory).Owner.EntityId;
                }
            }

            if (isMergeNeeded && hitGrid != null)
            {
                hitGrid.PasteBlocksToGrid(m_copiedGrids, inventoryOwnerId);
            }
            else
            {
                MyMultiplayer.RaiseStaticEvent(s => MyCubeGrid.TryPasteGrid_Implementation, m_copiedGrids, missingDefinitions, inventoryOwnerId);
            }

            if (deactivate)
            {
                Deactivate();
            }

            if (updateAfterPasteCallback != null)
            {
                updateAfterPasteCallback(pastedBuilders);
            }

            return true;
        }
        private bool PasteInternal(MyInventoryBase buildInventory, bool missingDefinitions, bool deactivate, List<MyObjectBuilder_CubeGrid> pastedBuilders = null, List<MyCubeGrid> touchingGrids = null,
            UpdateAfterPasteCallback updateAfterPasteCallback = null, bool multiBlock = false)
        {
            MyGuiAudio.PlaySound(MyGuiSounds.HudPlaceBlock);

            var grid = m_copiedGrids[0];
            bool isMergeNeeded = IsSnapped && SnapMode == MyGridPlacementSettings.SnapMode.Base6Directions && m_hitEntity is MyCubeGrid && grid != null && ((MyCubeGrid)m_hitEntity).GridSizeEnum == grid.GridSizeEnum;
           
            MyCubeGrid hitGrid = null;
            if(isMergeNeeded)
            {
                hitGrid = m_hitEntity as MyCubeGrid;
            }

            isMergeNeeded |= touchingGrids != null && touchingGrids.Count > 0;

            if(hitGrid == null && touchingGrids != null && touchingGrids.Count > 0)
            {
                hitGrid = touchingGrids[0];
            }

            long hitEntityId = hitGrid != null ? hitGrid.EntityId : 0;

            int i = 0;
            foreach (var gridBuilder in m_copiedGrids)
            {
                gridBuilder.CreatePhysics = true;
                gridBuilder.EnableSmallToLargeConnections = true;
                bool savedStaticFlag = gridBuilder.IsStatic;

                gridBuilder.PositionAndOrientation = new MyPositionAndOrientation(m_previewGrids[i].WorldMatrix);
                gridBuilder.PositionAndOrientation.Value.Orientation.Normalize();
                i++;
            }

            long inventoryOwnerId = 0;

            if (buildInventory != null)
            {
                if (MyFakes.ENABLE_MEDIEVAL_INVENTORY)
                {
                    inventoryOwnerId = buildInventory.Entity.EntityId;
                }
                else if( buildInventory is MyInventory)
                {
                    inventoryOwnerId = (buildInventory as MyInventory).Owner.EntityId;
                }
            }

            bool isAdmin = MySession.Static.IsAdminModeEnabled(Sync.MyId);

            if (isMergeNeeded && hitGrid != null)
            {
                hitGrid.PasteBlocksToGrid(m_copiedGrids, inventoryOwnerId, multiBlock, isAdmin);
            }
            else if(CreationMode)
            {
                MyMultiplayer.RaiseStaticEvent(s => MyCubeGrid.TryCreateGrid_Implementation, CubeSize, IsStatic, m_copiedGrids[0].PositionAndOrientation.Value, inventoryOwnerId, isAdmin);
                CreationMode = false;
            }
            else if (MyPerGameSettings.Game == GameEnum.ME_GAME || MySession.Static.CreativeMode || MySession.Static.HasAdminRights)
            {
                MyMultiplayer.RaiseStaticEvent(s => MyCubeGrid.TryPasteGrid_Implementation, m_copiedGrids, missingDefinitions, inventoryOwnerId, m_objectVelocity, multiBlock, isAdmin);
            }

            if (deactivate)
            {
                Deactivate(afterPaste: true);
            }

            if (updateAfterPasteCallback != null)
            {
                updateAfterPasteCallback(pastedBuilders);
            }
           
            return true;
        }