class ActionRaw implements Sc2ApiSerializable<Raw.ActionRaw>, GeneralizableAbility<ActionRaw> {

    @Override
    public ActionRaw generalizeAbility(UnaryOperator<Ability> generalize) {
        Optional<ActionRawUnitCommand> commandUnit = getUnitCommand();
        Optional<ActionRawCameraMove> commandCamera = getCameraMove();
        Optional<ActionRawToggleAutocast> commandAutocast = getToggleAutocast();
        if (commandUnit.isPresent()) {
            return ActionRaw.of(commandUnit.get().generalizeAbility(generalize));
        }
        if (commandCamera.isPresent()) {
            return this;
        }
        if (commandAutocast.isPresent()) {
            return ActionRaw.of(commandAutocast.get().generalizeAbility(generalize));
        }
        throw new AssertionError("Invalid state: one of action case must be set.");
    }

    private  ActionRaw(Raw.ActionRaw sc2ApiActionRaw);
    private  ActionRaw(ActionRawUnitCommand unitCommand);
    private  ActionRaw(ActionRawCameraMove cameraMove);
    private  ActionRaw(ActionRawToggleAutocast toggleAutocast);

}