private static void completeOperationThrows(
      CollectInfo collectInfo,
      Operation operation,
      MethodAnnotationInfo mai,
      List<? extends IntrospectionHelper> introspectionHelper) {
    Class<?>[] thrownClasses = mai.getJavaMethod().getExceptionTypes();
    if (thrownClasses != null) {
      for (Class<?> thrownClass : thrownClasses) {
        ThrowableAnnotationInfo throwableAnnotationInfo =
            AnnotationUtils.getInstance().getThrowableAnnotationInfo(thrownClass);
        if (throwableAnnotationInfo != null) {
          int statusCode = throwableAnnotationInfo.getStatus().getCode();
          Response response = new Response();
          response.setCode(statusCode);
          response.setName(Status.valueOf(statusCode).getReasonPhrase());
          response.setMessage("Status " + statusCode);

          Class<?> outputPayloadType =
              throwableAnnotationInfo.isSerializable() ? thrownClass : StatusInfo.class;
          TypeInfo outputTypeInfo = null;
          try {
            outputTypeInfo = Types.getTypeInfo(outputPayloadType, null);
          } catch (UnsupportedTypeException e) {
            LOGGER.warning(
                "Could not add output payload for exception "
                    + thrownClass
                    + " throws by method "
                    + mai.getJavaMethod()
                    + ". "
                    + e.getMessage());
            continue;
          }

          RepresentationCollector.addRepresentation(
              collectInfo, outputTypeInfo, introspectionHelper);

          PayLoad outputPayLoad = new PayLoad();
          outputPayLoad.setType(outputTypeInfo.getRepresentationName());
          response.setOutputPayLoad(outputPayLoad);
          operation.getResponses().add(response);
        }
      }
    }
  }
  private static void completeOperationOutput(
      CollectInfo collectInfo,
      Operation operation,
      MethodAnnotationInfo mai,
      List<? extends IntrospectionHelper> introspectionHelper) {
    Response response = new Response();

    if (mai.getJavaMethod().getReturnType() != Void.TYPE) {
      TypeInfo outputTypeInfo;
      try {
        outputTypeInfo =
            Types.getTypeInfo(
                mai.getJavaMethod().getReturnType(), mai.getJavaMethod().getGenericReturnType());
      } catch (UnsupportedTypeException e) {
        LOGGER.warning(
            "Could not add output representation of method "
                + mai.getJavaMethod()
                + ". "
                + e.getMessage());
        return;
      }
      // Output representation
      RepresentationCollector.addRepresentation(collectInfo, outputTypeInfo, introspectionHelper);

      PayLoad outputEntity = new PayLoad();
      outputEntity.setType(outputTypeInfo.getRepresentationName());
      outputEntity.setArray(outputTypeInfo.isList());

      response.setOutputPayLoad(outputEntity);

      response.setCode(Status.SUCCESS_OK.getCode());
      response.setName(Status.SUCCESS_OK.getReasonPhrase());
      response.setDescription("");
      response.setMessage(Status.SUCCESS_OK.getDescription());
    } else {
      response.setCode(Status.SUCCESS_NO_CONTENT.getCode());
      response.setName(Status.SUCCESS_NO_CONTENT.getReasonPhrase());
      response.setDescription("");
      response.setMessage(Status.SUCCESS_NO_CONTENT.getDescription());
    }

    operation.getResponses().add(response);
  }
  private static void completeOperationInput(
      CollectInfo collectInfo,
      Operation operation,
      MethodAnnotationInfo mai,
      ServerResource sr,
      List<? extends IntrospectionHelper> introspectionHelper,
      MetadataService metadataService) {
    Class<?>[] inputClasses = mai.getJavaMethod().getParameterTypes();
    if (inputClasses != null && inputClasses.length > 0) {

      // Input representation
      // Handles only the first method parameter
      TypeInfo inputTypeInfo;
      try {
        inputTypeInfo =
            Types.getTypeInfo(inputClasses[0], mai.getJavaMethod().getGenericParameterTypes()[0]);
      } catch (UnsupportedTypeException e) {
        LOGGER.warning(
            "Could not add input representation of method"
                + mai.getJavaMethod()
                + ". "
                + e.getMessage());
        return;
      }

      RepresentationCollector.addRepresentation(collectInfo, inputTypeInfo, introspectionHelper);

      PayLoad inputEntity = new PayLoad();
      inputEntity.setType(inputTypeInfo.getRepresentationName());
      inputEntity.setArray(inputTypeInfo.isList());
      operation.setInputPayLoad(inputEntity);

      // Consumes
      if (metadataService != null) {

        try {
          List<Variant> requestVariants =
              mai.getRequestVariants(metadataService, sr.getConverterService());

          if (requestVariants == null || requestVariants.isEmpty()) {
            LOGGER.warning(
                "Could not add consumes of method "
                    + mai.getJavaMethod()
                    + ". There is no requested variant");
            return;
          }

          // une representation per variant ?
          for (Variant variant : requestVariants) {

            if (variant.getMediaType() == null) {
              LOGGER.warning("Variant has no media type: " + variant);
              continue;
            }

            operation.getConsumes().add(variant.getMediaType().getName());
          }
        } catch (IOException e) {
          throw new ResourceException(e);
        }
      }
    }
  }