/**
   * We are allowing consumers of the SDK to register their own deriived classes from the base
   * models we have inside the SDK. This allows for cases where the consumer wants to add addtional
   * flags and functions to the model and yet have orginal parsed objects of his liking. Example
   * SFFile does not provide the isSynced flag. The consumer app can extend like :
   *
   * <p>SFFileEx extends SFFile <br>
   * { <br>
   * boolean mIsSync <br>
   * }
   *
   * @throws IllegalAccessException
   * @throws InstantiationException
   * @throws SFInvalidTypeException
   */
  public static void registerSubClass(SFV3ElementType elementType, Class<?> newClass)
      throws InstantiationException, IllegalAccessException, SFInvalidTypeException {
    if (newClass == null) {
      throw new SFInvalidTypeException(
          " NULL does not extend " + elementType.mOriginalClass.toString());
    }

    // test if the new class is a real extension of the type being replaced.
    if (!elementType.mOriginalClass.isInstance(newClass.newInstance())) {
      String msg =
          newClass.toString() + " does not extend " + elementType.mOriginalClass.toString();

      Logger.d(TAG, msg);

      throw new SFInvalidTypeException(msg);
    }

    Logger.d(
        TAG,
        "Successfully registered : "
            + newClass.toString()
            + " to replace "
            + elementType.mOriginalClass.toString());

    elementType.mOverrideClass = newClass;

    registerSubClass(elementType.mToString.replace(prefix, "").replace(suffix, ""), newClass);
  }
  public static void registerSubClass(String originalClassName, Class<?> newClass)
      throws InstantiationException, IllegalAccessException, SFInvalidTypeException {
    if (newClass == null || originalClassName == null) {
      throw new SFInvalidTypeException(" NULL classes not allowed ");
    }

    Class originalClass = SFEntityTypeMap.getEntityTypeMap().get(originalClassName);

    if (originalClass == null) {
      throw new SFInvalidTypeException("Given Class does not exist");
    }

    // test if the new class is a real extension of the type being replaced.
    if (!originalClass.isInstance(newClass.newInstance())) {
      String msg = newClass.toString() + " does not extend " + originalClass.toString();

      Logger.d(TAG, msg);

      throw new SFInvalidTypeException(msg);
    }

    SFEntityTypeMap.getEntityTypeMap().put(originalClassName, newClass);
    SFDefaultGsonParser.routeSpecialClasses(originalClassName, newClass);

    Logger.d(
        TAG,
        "Successfully registered : "
            + newClass.toString()
            + " to replace "
            + originalClass.toString());
  }