diff --git a/vtm/src/org/oscim/layers/tile/vector/labeling/LabelPlacement.java b/vtm/src/org/oscim/layers/tile/vector/labeling/LabelPlacement.java
index 4ca4fc6c..33ae789c 100644
--- a/vtm/src/org/oscim/layers/tile/vector/labeling/LabelPlacement.java
+++ b/vtm/src/org/oscim/layers/tile/vector/labeling/LabelPlacement.java
@@ -12,11 +12,15 @@ import org.oscim.map.Map;
 import org.oscim.renderer.bucket.SymbolBucket;
 import org.oscim.renderer.bucket.SymbolItem;
 import org.oscim.renderer.bucket.TextItem;
+import org.oscim.theme.styles.TextStyle;
 import org.oscim.utils.FastMath;
 import org.oscim.utils.geom.OBB2D;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class LabelPlacement {
 	static final boolean dbg = false;
+	static final Logger log = LoggerFactory.getLogger(LabelPlacement.class);
 
 	public final static LabelTileData getLabels(MapTile tile) {
 		return (LabelTileData) tile.getData(LabelLayer.LABEL_DATA);
@@ -52,31 +56,10 @@ public class LabelPlacement {
 	private Label removeLabel(Label l) {
 		Label ret = (Label) l.next;
 		mLabels = (Label) mPool.release(mLabels, l);
-
 		return ret;
 	}
 
 	public void addLabel(Label l) {
-		for (Label o = mLabels; o != null; o = (Label) o.next) {
-			/* find other label with same text style */
-			if (l.text == o.text) {
-				while (o.next != null
-				        /* break if next item uses different text style */
-				        && l.text == o.next.text
-				        /* check same string instance */
-				        && l.string != o.string
-				        /* check same string */
-				        && !l.string.equals(o.string))
-					o = (Label) o.next;
-
-				/* Note: required for 'packing test' in prepare to work */
-				Label.shareText(l, o);
-				/* insert after text of same type or before same string */
-				l.next = o.next;
-				o.next = l;
-				return;
-			}
-		}
 		l.next = mLabels;
 		mLabels = l;
 	}
@@ -291,7 +274,6 @@ public class LabelPlacement {
 		boolean changedTiles = mTileRenderer.getVisibleTiles(mTileSet);
 
 		if (mTileSet.cnt == 0) {
-			//log.debug("no tiles "+ mTileSet.getSerial());
 			return false;
 		}
 
@@ -481,7 +463,7 @@ public class LabelPlacement {
 		l = (Label) mPool.release(l);
 
 		/* draw text to bitmaps and create vertices */
-		work.textLayer.labels = mLabels;
+		work.textLayer.labels = groupLabels(mLabels);
 		work.textLayer.prepare();
 		work.textLayer.labels = null;
 
@@ -495,4 +477,43 @@ public class LabelPlacement {
 		mLabels = (Label) mPool.releaseAll(mLabels);
 		mTileSet.releaseTiles();
 	}
+
+	/** group labels by string and type */
+	protected Label groupLabels(Label labels) {
+		for (Label cur = labels; cur != null; cur = (Label) cur.next) {
+			/* keep pointer to previous for removal */
+			Label p = cur;
+			TextStyle t = cur.text;
+			float w = cur.width;
+
+			/* iterate through following */
+			for (Label l = (Label) cur.next; l != null; l = (Label) l.next) {
+
+				if (w != l.width || t != l.text || !cur.string.equals(l.string)) {
+					p = l;
+					continue;
+				} else if (cur.next == l) {
+					l.string = cur.string;
+					p = l;
+					continue;
+				}
+				l.string = cur.string;
+
+				/* insert l after cur */
+				Label tmp = (Label) cur.next;
+				cur.next = l;
+
+				/* continue outer loop at l */
+				cur = l;
+
+				/* remove l from previous place */
+				p.next = l.next;
+				l.next = tmp;
+
+				/* continue from previous */
+				l = p;
+			}
+		}
+		return labels;
+	}
 }
diff --git a/vtm/src/org/oscim/utils/pool/Pool.java b/vtm/src/org/oscim/utils/pool/Pool.java
index 4e623288..7a9a529b 100644
--- a/vtm/src/org/oscim/utils/pool/Pool.java
+++ b/vtm/src/org/oscim/utils/pool/Pool.java
@@ -85,9 +85,7 @@ public abstract class Pool<T extends Inlist<?>> {
 
 		clearItem(item);
 
-		Inlist.remove((Inlist) list, item);
-
-		return list;
+		return (T) Inlist.remove((Inlist) list, item);
 	}
 
 	/** get an item from pool */