private ATypeTag getTargetTypeTag(ATypeTag expectedTypeTag, IAType aObjectType)
     throws IOException {
   if (aObjectType == null) {
     return expectedTypeTag;
   }
   if (aObjectType.getTypeTag() != ATypeTag.UNION) {
     final ATypeTag typeTag = aObjectType.getTypeTag();
     if (ATypeHierarchy.canPromote(expectedTypeTag, typeTag)
         || ATypeHierarchy.canDemote(expectedTypeTag, typeTag)) {
       return typeTag;
     } else {
       return null;
     }
     //            return ATypeHierarchy.canPromote(expectedTypeTag, typeTag) ? typeTag : null;
   } else { // union
     List<IAType> unionList = ((AUnionType) aObjectType).getUnionList();
     for (IAType t : unionList) {
       final ATypeTag typeTag = t.getTypeTag();
       if (ATypeHierarchy.canPromote(expectedTypeTag, typeTag)
           || ATypeHierarchy.canDemote(expectedTypeTag, typeTag)) {
         return typeTag;
       }
     }
   }
   return null;
 }
  private void parseAndCastNumeric(ATypeTag typeTag, IAType objectType, DataOutput out)
      throws AsterixException, IOException {
    final ATypeTag targetTypeTag = getTargetTypeTag(typeTag, objectType);
    DataOutput dataOutput = out;
    if (targetTypeTag != typeTag) {
      castBuffer.reset();
      dataOutput = castBuffer.getDataOutput();
    }

    if (targetTypeTag == null || !parseValue(admLexer.getLastTokenImage(), typeTag, dataOutput)) {
      throw new ParseException(
          mismatchErrorMessage + objectType.getTypeName() + mismatchErrorMessage2 + typeTag);
    }

    // If two type tags are not the same, either we try to promote or demote source type to the
    // target type
    if (targetTypeTag != typeTag) {
      if (ATypeHierarchy.canPromote(typeTag, targetTypeTag)) {
        // can promote typeTag to targetTypeTag
        ITypeConvertComputer promoteComputer =
            ATypeHierarchy.getTypePromoteComputer(typeTag, targetTypeTag);
        if (promoteComputer == null) {
          throw new AsterixException(
              "Can't cast the " + typeTag + " type to the " + targetTypeTag + " type.");
        }
        // do the promotion; note that the type tag field should be skipped
        promoteComputer.convertType(
            castBuffer.getByteArray(),
            castBuffer.getStartOffset() + 1,
            castBuffer.getLength() - 1,
            out);
      } else if (ATypeHierarchy.canDemote(typeTag, targetTypeTag)) {
        // can demote source type to the target type
        ITypeConvertComputer demoteComputer =
            ATypeHierarchy.getTypeDemoteComputer(typeTag, targetTypeTag);
        if (demoteComputer == null) {
          throw new AsterixException(
              "Can't cast the " + typeTag + " type to the " + targetTypeTag + " type.");
        }
        // do the demotion; note that the type tag field should be skipped
        demoteComputer.convertType(
            castBuffer.getByteArray(),
            castBuffer.getStartOffset() + 1,
            castBuffer.getLength() - 1,
            out);
      }
    }
  }