private ModifierGenerator(
      final PluginContext pluginContext,
      final DefinedTypeOutline classOutline,
      final String modifierClassName,
      final String modifierInterfaceName,
      final Collection<TypeOutline> interfaces,
      final String modifierMethodName,
      final boolean implement)
      throws JClassAlreadyExistsException {
    this.classOutline = classOutline;
    final JDefinedClass definedClass = classOutline.getImplClass();
    this.implement = implement;
    this.modifierClass =
        definedClass._class(
            JMod.PUBLIC, modifierClassName, classOutline.getImplClass().getClassType());
    if (interfaces != null) {
      for (final TypeOutline interfaceOutline : interfaces) {
        this.modifierClass._implements(
            pluginContext.ref(interfaceOutline.getImplClass(), modifierInterfaceName, true));
      }
    }
    final JFieldRef cachedModifierField;
    if (!"java.lang.Object".equals(definedClass._extends().fullName())) {
      this.modifierClass._extends(
          pluginContext.ref(definedClass._extends(), modifierClassName, false));
      cachedModifierField = JExpr.refthis(ModifierGenerator.MODIFIER_CACHE_FIELD_NAME);
    } else {
      if (implement) {
        cachedModifierField =
            JExpr._this()
                .ref(
                    definedClass.field(
                        JMod.PROTECTED | JMod.TRANSIENT,
                        this.modifierClass,
                        ModifierGenerator.MODIFIER_CACHE_FIELD_NAME));
      } else {
        cachedModifierField = null;
      }
    }

    final JDefinedClass typeDefinition =
        classOutline.isInterface()
                && ((DefinedInterfaceOutline) classOutline).getSupportInterface() != null
            ? ((DefinedInterfaceOutline) classOutline).getSupportInterface()
            : definedClass;
    final JMethod modifierMethod =
        typeDefinition.method(JMod.PUBLIC, this.modifierClass, modifierMethodName);
    if (this.implement) {
      final JConditional ifCacheNull =
          modifierMethod.body()._if(JExpr._null().eq(cachedModifierField));
      ifCacheNull._then().assign(cachedModifierField, JExpr._new(this.modifierClass));
      modifierMethod.body()._return(JExpr.cast(this.modifierClass, cachedModifierField));
    }
  }