public static boolean isSafeConversion(PsiType target, PsiType source) {
    /*  From \ To  byte short char int long float double
     *  byte        +    +    -    +    +    +    +
     *  short       -    +    -    +    +    +    +
     *  char        -    -    +    +    +    +    +
     *  int         -    -    -    +    +    -    +
     *  long        -    -    -    -    +    -    -
     *  float       -    -    -    -    -    +    +
     *  double      -    -    -    -    -    -    +
     */
    if (target == null || source == null) return false;
    if (target.equals(source)) return true;

    int sourceRank = TYPE_TO_RANK_MAP.get(source);
    int targetRank = TYPE_TO_RANK_MAP.get(target);
    if (sourceRank == -1 || sourceRank > MAX_NUMERIC_RANK ||
        targetRank == -1 || targetRank > MAX_NUMERIC_RANK ||
        !IS_ASSIGNABLE_BIT_SET[sourceRank-1][targetRank-1]) {
      return false;
    }
    if (PsiTypes.intType().equals(source) && PsiTypes.floatType().equals(target)) return false;
    if (PsiTypes.longType().equals(source) && isFloatOrDoubleType(target)) return false;
    return true;
  }
public static boolean isSafeConversion(PsiType target, PsiType source)