public final MapleCharacter killBy(final MapleCharacter killer) {
	int totalBaseExp = (int) (Math.min(Integer.MAX_VALUE, (getMobExp() * (killer.getLevel() <= 10 ? 1 : killer.getClient().getChannelServer().getExpRate()))));
	AttackerEntry highest = null;
	int highdamage = 0;
	for (final AttackerEntry attackEntry : attackers) {
	    if (attackEntry.getDamage() > highdamage) {
		highest = attackEntry;
		highdamage = attackEntry.getDamage();
	    }
	}
	int baseExp;
	for (final AttackerEntry attackEntry : attackers) {
	    baseExp = (int) Math.ceil(totalBaseExp * ((double) attackEntry.getDamage() / getMobMaxHp()));
	    attackEntry.killedMob(killer.getMap(), baseExp, attackEntry == highest);
	}
	final MapleCharacter controll = controller.get();
	if (controll != null) { // this can/should only happen when a hidden gm attacks the monster
	    controll.getClient().getSession().write(MobPacket.stopControllingMonster(getObjectId()));
	    controll.stopControllingMonster(this);
	}
	spawnRevives(killer.getMap());
	if (eventInstance != null) {
	    eventInstance.unregisterMonster(this);
	    eventInstance = null;
	}
	sponge = null;

	if (listener != null) {
	    listener.monsterKilled();
	}
	final MapleCharacter ret = highestDamageChar;
	highestDamageChar = null; // may not keep hard references to chars outside of PlayerStorage or MapleMap
	return ret;
    }