gt:                     MorphState state = e.getValue().get(i);
context: package morph.common.core;
  
  import cpw.mods.fml.common.FMLCommonHandler;
  import cpw.mods.fml.common.eventhandler.SubscribeEvent;
  import cpw.mods.fml.common.gameevent.TickEvent;
  import ichun.common.core.EntityHelperBase;
  import ichun.common.core.network.PacketHandler;
  import ichun.common.core.util.ObfHelper;
  import morph.api.Ability;
  import morph.common.Morph;
  import morph.common.ability.AbilityFly;
  import morph.common.ability.AbilityHandler;
  import morph.common.morph.MorphInfo;
  import morph.common.morph.MorphState;
  import morph.common.packet.PacketCompleteDemorph;
  import morph.common.packet.PacketSession;
  import net.minecraft.entity.SharedMonsterAttributes;
  import net.minecraft.entity.player.EntityPlayer;
  import net.minecraft.nbt.NBTTagCompound;
  import net.minecraft.util.MathHelper;
  import net.minecraft.world.World;
  import net.minecraft.world.WorldServer;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map.Entry;
  import java.util.WeakHashMap;
  
  public class TickHandlerServer
  {
  
      @SubscribeEvent
      public void worldTick(TickEvent.WorldTickEvent event)
      {
          if(event.phase == TickEvent.Phase.END && event.side.isServer())
          {
              //Post world tick
              WorldServer world = (WorldServer)event.world;
              if(clock != world.getWorldTime() || !world.getGameRules().getGameRuleBooleanValue("doDaylightCycle"))
              {
                  clock = world.getWorldTime();
                  //						for(int i = 0 ; i < world.loadedEntityList.size(); i++)
                  //						{
                  //							if(world.loadedEntityList.get(i) instanceof EntityCow)
                  //							{
                  //								((EntityCow)world.loadedEntityList.get(i)).setDead();
                  //							}
                  //						}
              }
          }
      }
  
      @SubscribeEvent
      public void playerTick(TickEvent.PlayerTickEvent event)
      {
          if(event.phase == TickEvent.Phase.END && event.side.isServer())
          {
              EntityPlayer player = event.player;
              MorphInfo info = getPlayerMorphInfo(player);
              if(info != null)
              {
                  float prog = info.morphProgress > 10 ? (((float)info.morphProgress) / 60F) : 0.0F;
                  if(prog > 1.0F)
                  {
                      prog = 1.0F;
                  }
  
                  prog = (float)Math.pow(prog, 2);
  
                  float prev = info.prevState != null && !(info.prevState.entInstance instanceof EntityPlayer) ? info.prevState.entInstance.getEyeHeight() : player.yOffset;
                  float next = info.nextState != null && !(info.nextState.entInstance instanceof EntityPlayer) ? info.nextState.entInstance.getEyeHeight() : player.yOffset;
                  double ySize = player.yOffset - (prev + (next - prev) * prog);
                  player.lastTickPosY += ySize;
                  player.prevPosY += ySize;
                  player.posY += ySize;
              }
              //            ArrayList<MorphState> states = getPlayerMorphs(event.player.worldObj, "ohaiiChun");
              //            for(MorphState state : states)
              //            {
              //                System.out.println(state.identifier);
              //            }
          }
      }
  
      @SubscribeEvent
      public void serverTick(TickEvent.ServerTickEvent event)
      {
          if(event.phase == TickEvent.Phase.END)
          {
              Iterator<Entry<String, MorphInfo>> ite = playerMorphInfo.entrySet().iterator();
              while(ite.hasNext())
              {
                  Entry<String, MorphInfo> e = ite.next();
                  MorphInfo info = e.getValue();
  
                  EntityPlayer player = FMLCommonHandler.instance().getMinecraftServerInstance().getConfigurationManager().func_152612_a(info.playerName);
  
                  if(info.getMorphing())
                  {
                      info.morphProgress++;
                      if(info.morphProgress > 80)
                      {
                          info.morphProgress = 80;
                          info.setMorphing(false);
  
                          if(player != null)
                          {
                              player.setSize(info.nextState.entInstance.width, info.nextState.entInstance.height);
                              player.setPosition(player.posX, player.posY, player.posZ);
                              player.eyeHeight = info.nextState.entInstance instanceof EntityPlayer ? ((EntityPlayer)info.nextState.entInstance).getDefaultEyeHeight() : info.nextState.entInstance.getEyeHeight() - player.yOffset;
  
                              double nextMaxHealth = MathHelper.clamp_double(info.nextState.entInstance.getEntityAttribute(SharedMonsterAttributes.maxHealth).getBaseValue(), 1D, 20D) + info.healthOffset;
  
                              if(nextMaxHealth < 1D)
                              {
                                  nextMaxHealth = 1D;
                              }
  
                              if(nextMaxHealth != player.getEntityAttribute(SharedMonsterAttributes.maxHealth).getBaseValue())
                              {
                                  player.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(nextMaxHealth);
                              }
  
                              ArrayList<Ability> newAbilities = AbilityHandler.getEntityAbilities(info.nextState.entInstance.getClass());
                              ArrayList<Ability> oldAbilities = info.morphAbilities;
                              info.morphAbilities = new ArrayList<Ability>();
                              for(Ability ability : newAbilities)
                              {
                                  try
                                  {
                                      Ability clone = ability.clone();
                                      clone.setParent(player);
                                      info.morphAbilities.add(clone);
                                  }
                                  catch(Exception e1)
                                  {
                                  }
                              }
                              for(Ability ability : oldAbilities)
                              {
                                  if(ability.inactive)
                                  {
                                      continue;
                                  }
                                  boolean isRemoved = true;
                                  for(Ability newAbility : info.morphAbilities)
                                  {
                                      if(newAbility.getType().equalsIgnoreCase(ability.getType()))
                                      {
                                          isRemoved = false;
                                          break;
                                      }
                                  }
                                  if(isRemoved && ability.getParent() != null)
                                  {
                                      ability.kill();
                                  }
                              }
                          }
  
                          if(info.nextState.playerMorph.equalsIgnoreCase(e.getKey()))
                          {
                              //Demorphed
                              PacketHandler.sendToAll(Morph.channels, new PacketCompleteDemorph(e.getKey()));
  
                              for(Ability ability : info.morphAbilities)
                              {
                                  if(ability.inactive)
                                  {
                                      continue;
                                  }
                                  if(ability.getParent() != null)
                                  {
                                      ability.kill();
                                  }
                              }
  
                              if(player != null)
                              {
                                  getMorphDataFromPlayer(player).removeTag("morphData");
                              }
  
                              ite.remove();
                          }
                      }
                      else if(info.prevState != null && player != null)
                      {
                          player.setSize(info.prevState.entInstance.width + (info.nextState.entInstance.width - info.prevState.entInstance.width) * ((float)info.morphProgress / 80F), info.prevState.entInstance.height + (info.nextState.entInstance.height - info.prevState.entInstance.height) * ((float)info.morphProgress / 80F));
                          player.setPosition(player.posX, player.posY, player.posZ);
                          float prevEyeHeight = info.prevState.entInstance instanceof EntityPlayer ? ((EntityPlayer)info.prevState.entInstance).getDefaultEyeHeight() : info.prevState.entInstance.getEyeHeight() - player.yOffset;
                          float nextEyeHeight = info.nextState.entInstance instanceof EntityPlayer ? ((EntityPlayer)info.nextState.entInstance).getDefaultEyeHeight() : info.nextState.entInstance.getEyeHeight() - player.yOffset;
                          player.eyeHeight = prevEyeHeight + (nextEyeHeight - prevEyeHeight) * ((float)info.morphProgress / 80F);
  
                          double prevMaxHealth = MathHelper.clamp_double(info.prevState.entInstance.getEntityAttribute(SharedMonsterAttributes.maxHealth).getBaseValue(), 1D, 20D);
                          double nextMaxHealth = MathHelper.clamp_double(info.nextState.entInstance.getEntityAttribute(SharedMonsterAttributes.maxHealth).getBaseValue(), 1D, 20D);
                          if(prevMaxHealth != nextMaxHealth)
                          {
                              double healthScale = info.preMorphHealth / prevMaxHealth;
                              double prevHealth = info.preMorphHealth;
                              double nextHealth = nextMaxHealth * healthScale;
                              if(healthScale <= 1.0D)
                              {
                                  float targetHealth = (float)(prevHealth + (nextHealth - prevHealth) * ((float)info.morphProgress / 80F));
                                  if(targetHealth < 1.0F)
                                  {
                                      targetHealth = 1.0F;
                                  }
                                  if((nextMaxHealth > prevMaxHealth && player.getHealth() + 0.5F < (float)Math.floor(targetHealth) || prevMaxHealth > nextMaxHealth) && player.isEntityAlive())
                                  {
                                      player.setHealth(targetHealth);
                                  }
                              }
  
                              double curMaxHealth = player.getEntityAttribute(SharedMonsterAttributes.maxHealth).getBaseValue();
                              double morphMaxHealth = Math.round(prevMaxHealth + (nextMaxHealth - prevMaxHealth) * ((float)info.morphProgress / 80F)) + info.healthOffset;
                              if(morphMaxHealth < 1D)
                              {
                                  morphMaxHealth = 1D;
                              }
  
                              if(morphMaxHealth != curMaxHealth)
                              {
                                  player.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(morphMaxHealth);
                              }
                          }
                      }
                  }
  
                  if(player != null)
                  {
                      //TODO check that the sleep timer doesn't affect the bounding box
                      //				if(player.isPlayerSleeping() && player.sleepTimer > 0)
                      if(player.isPlayerSleeping())
                      {
                          info.sleeping = true;
                      }
                      else if(info.sleeping)
                      {
                          info.sleeping = false;
                          player.setSize(info.nextState.entInstance.width, info.nextState.entInstance.height);
                          player.setPosition(player.posX, player.posY, player.posZ);
                          player.eyeHeight = info.nextState.entInstance instanceof EntityPlayer ? ((EntityPlayer)info.nextState.entInstance).getDefaultEyeHeight() : info.nextState.entInstance.getEyeHeight() - player.yOffset;
                      }
  
                      if(info.prevState != null)
                      {
                          info.prevState.entInstance.setEntityId(player.getEntityId());
                      }
                      if(info.nextState != null)
                      {
                          info.nextState.entInstance.setEntityId(player.getEntityId());
                      }
                  }
  
                  for(Ability ability : info.morphAbilities)
                  {
                      if(player != null && ability.getParent() == player || player == null && ability.getParent() != null)
                      {
                          if(ability.inactive)
                          {
                              continue;
                          }
                          ability.tick();
                          if(!info.firstUpdate && ability instanceof AbilityFly && player != null)
                          {
                              info.flying = player.capabilities.isFlying;
                          }
                      }
                      else
                      {
                          ability.setParent(player);
                      }
                  }
  
                  info.firstUpdate = false;
  
                  //					if(info.morphProgress > 70)
                  //					{
                  //						info.nextState.entInstance.isDead = false;
                  //						info.nextState.entInstance.setLocationAndAngles(player.posX, player.posY, player.posZ, player.rotationYaw, player.rotationPitch);
                  //						info.nextState.entInstance.onUpdate();
                  //					}
              }
  
              Iterator<Entry<EntityPlayer, ArrayList<MorphState>>> ite1 = saveList.entrySet().iterator();
              while(ite1.hasNext())
              {
                  Entry<EntityPlayer, ArrayList<MorphState>> e = ite1.next();
  
                  NBTTagCompound tag = getMorphDataFromPlayer(e.getKey());
  
                  tag.setInteger("morphStatesCount", e.getValue().size());
  
                  for(int i = 0; i < e.getValue().size(); i++)
                  {
  