public ProtectionEntry CreateProtection(
            TSPlayer player, DPoint tileLocation, bool checkIfBlockTypeProtectableByConfig = true,
            bool checkTShockBuildAndRegionAccess = true, bool checkLimits = true
            )
        {
            if (player == null)
            {
                throw new ArgumentNullException();
            }
            if (!(TerrariaUtils.Tiles[tileLocation] != null))
            {
                throw new ArgumentException("tileLocation");
            }
            if (!(TerrariaUtils.Tiles[tileLocation].active()))
            {
                throw new ArgumentException("tileLocation");
            }

            ITile tile      = TerrariaUtils.Tiles[tileLocation];
            int   blockType = tile.type;

            tileLocation = TerrariaUtils.Tiles.MeasureObject(tileLocation).OriginTileLocation;

            if (checkIfBlockTypeProtectableByConfig && !this.Config.ManuallyProtectableTiles[tile.type])
            {
                throw new InvalidBlockTypeException(blockType);
            }

            if (checkTShockBuildAndRegionAccess && !player.HasBuildPermission(tileLocation.X, tileLocation.Y))
            {
                throw new TileProtectedException(tileLocation);
            }

            if (
                checkLimits &&
                !player.Group.HasPermission(ProtectorPlugin.NoProtectionLimits_Permission) &&
                this.WorldMetadata.CountUserProtections(player.Account.ID) >= this.Config.MaxProtectionsPerPlayerPerWorld
                )
            {
                throw new LimitEnforcementException();
            }

            lock (this.WorldMetadata.Protections) {
                ProtectionEntry protection;

                if (this.WorldMetadata.Protections.TryGetValue(tileLocation, out protection))
                {
                    if (protection.Owner == player.Account.ID)
                    {
                        throw new AlreadyProtectedException();
                    }

                    throw new TileProtectedException(tileLocation);
                }

                protection = new ProtectionEntry(player.Account.ID, tileLocation, tile.type);
                this.WorldMetadata.Protections.Add(tileLocation, protection);

                return(protection);
            }
        }