Program: 15798
Project: 15798
Buggy source:
private Object unwrap(TemplateModel model,Class hint,Map recursionStops) throws TemplateModelException {
  if (model == nullModel) {
    return null;
  }
  boolean isBoolean=Boolean.TYPE == hint;
  boolean isChar=Character.TYPE == hint;
  if (model instanceof AdapterTemplateModel) {
    Object adapted=((AdapterTemplateModel)model).getAdaptedObject(hint);
    if (hint.isInstance(adapted)) {
      return adapted;
    }
    if (adapted instanceof Number && ((hint.isPrimitive() && !isChar && !isBoolean) || NUMBER_CLASS.isAssignableFrom(hint))) {
      Number number=convertUnwrappedNumber(hint,(Number)adapted);
      if (number != null) {
        return number;
      }
    }
  }
  if (model instanceof WrapperTemplateModel) {
    Object wrapped=((WrapperTemplateModel)model).getWrappedObject();
    if (hint.isInstance(wrapped)) {
      return wrapped;
    }
    if (wrapped instanceof Number && ((hint.isPrimitive() && !isChar && !isBoolean) || NUMBER_CLASS.isAssignableFrom(hint))) {
      Number number=convertUnwrappedNumber(hint,(Number)wrapped);
      if (number != null) {
        return number;
      }
    }
  }
  if (STRING_CLASS == hint) {
    if (model instanceof TemplateScalarModel) {
      return ((TemplateScalarModel)model).getAsString();
    }
    return CAN_NOT_UNWRAP;
  }
  if ((hint.isPrimitive() && !isChar && !isBoolean) || NUMBER_CLASS.isAssignableFrom(hint)) {
    if (model instanceof TemplateNumberModel) {
      Number number=convertUnwrappedNumber(hint,((TemplateNumberModel)model).getAsNumber());
      if (number != null) {
        return number;
      }
    }
  }
  if (isBoolean || BOOLEAN_CLASS == hint) {
    if (model instanceof TemplateBooleanModel) {
      return ((TemplateBooleanModel)model).getAsBoolean() ? Boolean.TRUE : Boolean.FALSE;
    }
    return CAN_NOT_UNWRAP;
  }
  if (MAP_CLASS == hint) {
    if (model instanceof TemplateHashModel) {
      return new HashAdapter((TemplateHashModel)model,this);
    }
  }
  if (LIST_CLASS == hint) {
    if (model instanceof TemplateSequenceModel) {
      return new SequenceAdapter((TemplateSequenceModel)model,this);
    }
  }
  if (SET_CLASS == hint) {
    if (model instanceof TemplateCollectionModel) {
      return new SetAdapter((TemplateCollectionModel)model,this);
    }
  }
  if (COLLECTION_CLASS == hint || ITERABLE_CLASS == hint) {
    if (model instanceof TemplateCollectionModel) {
      return new CollectionAdapter((TemplateCollectionModel)model,this);
    }
    if (model instanceof TemplateSequenceModel) {
      return new SequenceAdapter((TemplateSequenceModel)model,this);
    }
  }
  if (hint.isArray()) {
    if (model instanceof TemplateSequenceModel) {
      if (recursionStops != null) {
        Object retval=recursionStops.get(model);
        if (retval != null) {
          return retval;
        }
      }
 else {
        recursionStops=new IdentityHashMap();
      }
      TemplateSequenceModel seq=(TemplateSequenceModel)model;
      Class componentType=hint.getComponentType();
      Object array=Array.newInstance(componentType,seq.size());
      recursionStops.put(model,array);
      try {
        int size=seq.size();
        for (int i=0; i < size; i++) {
          Object val=unwrap(seq.get(i),componentType,recursionStops);
          if (val == CAN_NOT_UNWRAP) {
            return CAN_NOT_UNWRAP;
          }
          Array.set(array,i,val);
        }
      }
  finally {
        recursionStops.remove(model);
      }
      return array;
    }
    return CAN_NOT_UNWRAP;
  }
  if (isChar || hint == CHARACTER_CLASS) {
    if (model instanceof TemplateScalarModel) {
      String s=((TemplateScalarModel)model).getAsString();
      if (s.length() == 1) {
        return new Character(s.charAt(0));
      }
    }
    return CAN_NOT_UNWRAP;
  }
  if (DATE_CLASS.isAssignableFrom(hint)) {
    if (model instanceof TemplateDateModel) {
      Date date=((TemplateDateModel)model).getAsDate();
      if (hint.isInstance(date)) {
        return date;
      }
    }
  }
  if (model instanceof TemplateNumberModel) {
    Number number=((TemplateNumberModel)model).getAsNumber();
    if (hint.isInstance(number)) {
      return number;
    }
  }
  if (model instanceof TemplateDateModel) {
    Date date=((TemplateDateModel)model).getAsDate();
    if (hint.isInstance(date)) {
      return date;
    }
  }
  if (model instanceof TemplateScalarModel && hint.isAssignableFrom(STRING_CLASS)) {
    return ((TemplateScalarModel)model).getAsString();
  }
  if (model instanceof TemplateBooleanModel && hint.isAssignableFrom(BOOLEAN_CLASS)) {
    return ((TemplateBooleanModel)model).getAsBoolean() ? Boolean.TRUE : Boolean.FALSE;
  }
  if (model instanceof TemplateHashModel && hint.isAssignableFrom(HASHADAPTER_CLASS)) {
    return new HashAdapter((TemplateHashModel)model,this);
  }
  if (model instanceof TemplateSequenceModel && hint.isAssignableFrom(SEQUENCEADAPTER_CLASS)) {
    return new SequenceAdapter((TemplateSequenceModel)model,this);
  }
  if (model instanceof TemplateCollectionModel && hint.isAssignableFrom(SETADAPTER_CLASS)) {
    return new SetAdapter((TemplateCollectionModel)model,this);
  }
  if (hint.isInstance(model)) {
    return model;
  }
  return CAN_NOT_UNWRAP;
}

Fixed version (ground truth):
private Object unwrap(TemplateModel model,Class hint,Map recursionStops) throws TemplateModelException {
  if (model == null || model == nullModel) {
    return null;
  }
  boolean isBoolean=Boolean.TYPE == hint;
  boolean isChar=Character.TYPE == hint;
  if (model instanceof AdapterTemplateModel) {
    Object adapted=((AdapterTemplateModel)model).getAdaptedObject(hint);
    if (hint.isInstance(adapted)) {
      return adapted;
    }
    if (adapted instanceof Number && ((hint.isPrimitive() && !isChar && !isBoolean) || NUMBER_CLASS.isAssignableFrom(hint))) {
      Number number=convertUnwrappedNumber(hint,(Number)adapted);
      if (number != null) {
        return number;
      }
    }
  }
  if (model instanceof WrapperTemplateModel) {
    Object wrapped=((WrapperTemplateModel)model).getWrappedObject();
    if (hint.isInstance(wrapped)) {
      return wrapped;
    }
    if (wrapped instanceof Number && ((hint.isPrimitive() && !isChar && !isBoolean) || NUMBER_CLASS.isAssignableFrom(hint))) {
      Number number=convertUnwrappedNumber(hint,(Number)wrapped);
      if (number != null) {
        return number;
      }
    }
  }
  if (STRING_CLASS == hint) {
    if (model instanceof TemplateScalarModel) {
      return ((TemplateScalarModel)model).getAsString();
    }
    return CAN_NOT_UNWRAP;
  }
  if ((hint.isPrimitive() && !isChar && !isBoolean) || NUMBER_CLASS.isAssignableFrom(hint)) {
    if (model instanceof TemplateNumberModel) {
      Number number=convertUnwrappedNumber(hint,((TemplateNumberModel)model).getAsNumber());
      if (number != null) {
        return number;
      }
    }
  }
  if (isBoolean || BOOLEAN_CLASS == hint) {
    if (model instanceof TemplateBooleanModel) {
      return ((TemplateBooleanModel)model).getAsBoolean() ? Boolean.TRUE : Boolean.FALSE;
    }
    return CAN_NOT_UNWRAP;
  }
  if (MAP_CLASS == hint) {
    if (model instanceof TemplateHashModel) {
      return new HashAdapter((TemplateHashModel)model,this);
    }
  }
  if (LIST_CLASS == hint) {
    if (model instanceof TemplateSequenceModel) {
      return new SequenceAdapter((TemplateSequenceModel)model,this);
    }
  }
  if (SET_CLASS == hint) {
    if (model instanceof TemplateCollectionModel) {
      return new SetAdapter((TemplateCollectionModel)model,this);
    }
  }
  if (COLLECTION_CLASS == hint || ITERABLE_CLASS == hint) {
    if (model instanceof TemplateCollectionModel) {
      return new CollectionAdapter((TemplateCollectionModel)model,this);
    }
    if (model instanceof TemplateSequenceModel) {
      return new SequenceAdapter((TemplateSequenceModel)model,this);
    }
  }
  if (hint.isArray()) {
    if (model instanceof TemplateSequenceModel) {
      if (recursionStops != null) {
        Object retval=recursionStops.get(model);
        if (retval != null) {
          return retval;
        }
      }
 else {
        recursionStops=new IdentityHashMap();
      }
      TemplateSequenceModel seq=(TemplateSequenceModel)model;
      Class componentType=hint.getComponentType();
      Object array=Array.newInstance(componentType,seq.size());
      recursionStops.put(model,array);
      try {
        int size=seq.size();
        for (int i=0; i < size; i++) {
          Object val=unwrap(seq.get(i),componentType,recursionStops);
          if (val == CAN_NOT_UNWRAP) {
            return CAN_NOT_UNWRAP;
          }
          Array.set(array,i,val);
        }
      }
  finally {
        recursionStops.remove(model);
      }
      return array;
    }
    return CAN_NOT_UNWRAP;
  }
  if (isChar || hint == CHARACTER_CLASS) {
    if (model instanceof TemplateScalarModel) {
      String s=((TemplateScalarModel)model).getAsString();
      if (s.length() == 1) {
        return new Character(s.charAt(0));
      }
    }
    return CAN_NOT_UNWRAP;
  }
  if (DATE_CLASS.isAssignableFrom(hint)) {
    if (model instanceof TemplateDateModel) {
      Date date=((TemplateDateModel)model).getAsDate();
      if (hint.isInstance(date)) {
        return date;
      }
    }
  }
  if (model instanceof TemplateNumberModel) {
    Number number=((TemplateNumberModel)model).getAsNumber();
    if (hint.isInstance(number)) {
      return number;
    }
  }
  if (model instanceof TemplateDateModel) {
    Date date=((TemplateDateModel)model).getAsDate();
    if (hint.isInstance(date)) {
      return date;
    }
  }
  if (model instanceof TemplateScalarModel && hint.isAssignableFrom(STRING_CLASS)) {
    return ((TemplateScalarModel)model).getAsString();
  }
  if (model instanceof TemplateBooleanModel && hint.isAssignableFrom(BOOLEAN_CLASS)) {
    return ((TemplateBooleanModel)model).getAsBoolean() ? Boolean.TRUE : Boolean.FALSE;
  }
  if (model instanceof TemplateHashModel && hint.isAssignableFrom(HASHADAPTER_CLASS)) {
    return new HashAdapter((TemplateHashModel)model,this);
  }
  if (model instanceof TemplateSequenceModel && hint.isAssignableFrom(SEQUENCEADAPTER_CLASS)) {
    return new SequenceAdapter((TemplateSequenceModel)model,this);
  }
  if (model instanceof TemplateCollectionModel && hint.isAssignableFrom(SETADAPTER_CLASS)) {
    return new SetAdapter((TemplateCollectionModel)model,this);
  }
  if (hint.isInstance(model)) {
    return model;
  }
  return CAN_NOT_UNWRAP;
}