diff --git a/src/me/ryanhamshire/GriefPrevention/EntityCleanupTask.java b/src/me/ryanhamshire/GriefPrevention/EntityCleanupTask.java
new file mode 100644
index 0000000..4816693
--- /dev/null
+++ b/src/me/ryanhamshire/GriefPrevention/EntityCleanupTask.java
@@ -0,0 +1,143 @@
+/*
+ GriefPrevention Server Plugin for Minecraft
+ Copyright (C) 2011 Ryan Hamshire
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+package me.ryanhamshire.GriefPrevention;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.bukkit.Material;
+import org.bukkit.World;
+import org.bukkit.entity.Boat;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.Player;
+import org.bukkit.entity.Vehicle;
+
+//FEATURE: creative mode worlds get a regular entity cleanup
+
+//this main thread task revisits the location of a partially chopped tree from several minutes ago
+//if any part of the tree is still there and nothing else has been built in its place, remove the remaining parts
+class EntityCleanupTask implements Runnable
+{
+ //where to start cleaning in the list of entities
+ private double percentageStart;
+
+ public EntityCleanupTask(double percentageStart)
+ {
+ this.percentageStart = percentageStart;
+ }
+
+ @Override
+ public void run()
+ {
+ ArrayList worlds = GriefPrevention.instance.config_claims_enabledCreativeWorlds;
+
+ for(int i = 0; i < worlds.size(); i++)
+ {
+ World world = worlds.get(i);
+
+ List entities = world.getEntities();
+
+ //starting and stopping point. each execution of the task scans 10% of the server's (loaded) entities
+ int j = (int)(entities.size() * this.percentageStart);
+ int k = (int)(entities.size() * (this.percentageStart + .1));
+ Claim cachedClaim = null;
+ for(; j < entities.size() && j < k; j++)
+ {
+ Entity entity = entities.get(j);
+
+ boolean remove = false;
+ if(entity instanceof Boat) //boats must be occupied
+ {
+ Boat boat = (Boat)entity;
+ if(boat.isEmpty()) remove = true;
+ }
+
+ else if(entity instanceof Vehicle)
+ {
+ Vehicle vehicle = (Vehicle)entity;
+
+ //minecarts in motion must be occupied by a player
+ if(vehicle.getVelocity().lengthSquared() != 0)
+ {
+ if(vehicle.isEmpty() || !(vehicle.getPassenger() instanceof Player))
+ {
+ remove = true;
+ }
+ }
+
+ //stationary carts must be on rails
+ else
+ {
+ Material material = world.getBlockAt(vehicle.getLocation()).getType();
+ if(material != Material.RAILS && material != Material.POWERED_RAIL && material != Material.DETECTOR_RAIL)
+ {
+ remove = true;
+ }
+ }
+ }
+
+ //all non-player entities must be in claims
+ else if(!(entity instanceof Player))
+ {
+ Claim claim = GriefPrevention.instance.dataStore.getClaimAt(entity.getLocation(), false, cachedClaim);
+ if(claim != null)
+ {
+ cachedClaim = claim;
+ }
+ else
+ {
+ remove = true;
+ }
+ }
+
+ if(remove)
+ {
+ entity.remove();
+ }
+ }
+ }
+
+ //starting and stopping point. each execution of the task scans 5% of the server's claims
+ List claims = GriefPrevention.instance.dataStore.claims;
+ int j = (int)(claims.size() * this.percentageStart);
+ int k = (int)(claims.size() * (this.percentageStart + .05));
+ for(; j < claims.size() && j < k; j++)
+ {
+ Claim claim = claims.get(j);
+
+ //if it's a creative mode claim
+ if(GriefPrevention.instance.creativeRulesApply(claim.getLesserBoundaryCorner()))
+ {
+ //check its entity count and remove any extras
+ claim.allowMoreEntities();
+ }
+ }
+
+ //schedule the next run of this task, in 3 minutes (20L is approximately 1 second)
+ double nextRunPercentageStart = this.percentageStart + .05;
+ if(nextRunPercentageStart > .99)
+ {
+ nextRunPercentageStart = 0;
+ System.gc(); //clean up every hour
+ }
+
+ EntityCleanupTask task = new EntityCleanupTask(nextRunPercentageStart);
+ GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, task, 20L * 60 * 1);
+ }
+}