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);
        }
      }
    }
  }
  public static void collectResource(
      CollectInfo collectInfo,
      ServerResource sr,
      String basePath,
      ChallengeScheme scheme,
      List<? extends IntrospectionHelper> introspectionHelper) {
    Resource resource = getResource(collectInfo, sr, basePath, scheme);

    // add operations
    ArrayList<Operation> operations = new ArrayList<>();

    List<AnnotationInfo> annotations =
        sr.isAnnotated() ? AnnotationUtils.getInstance().getAnnotations(sr.getClass()) : null;

    if (annotations != null) {
      for (AnnotationInfo annotationInfo : annotations) {
        if (annotationInfo instanceof MethodAnnotationInfo) {
          MethodAnnotationInfo methodAnnotationInfo = (MethodAnnotationInfo) annotationInfo;

          Method method = methodAnnotationInfo.getRestletMethod();

          Operation operation = getOperationFromMethod(method);

          if (StringUtils.isNullOrEmpty(operation.getName())) {
            operation.setName(methodAnnotationInfo.getJavaMethod().getName());
          }

          completeOperation(collectInfo, operation, methodAnnotationInfo, sr, introspectionHelper);

          for (IntrospectionHelper helper : introspectionHelper) {
            List<Class<?>> representationClasses =
                helper.processOperation(
                    resource, operation, sr.getClass(), methodAnnotationInfo.getJavaMethod());
            if (representationClasses != null && !representationClasses.isEmpty()) {
              for (Class<?> representationClazz : representationClasses) {
                TypeInfo typeInfo;
                try {
                  typeInfo = Types.getTypeInfo(representationClazz, null);
                } catch (UnsupportedTypeException e) {
                  LOGGER.warning(
                      "Could not add representation class "
                          + representationClazz.getName()
                          + ". "
                          + e.getMessage());
                  continue;
                }
                RepresentationCollector.addRepresentation(
                    collectInfo, typeInfo, introspectionHelper);
              }
            }
          }
          operations.add(operation);
        }
      }
      if (!operations.isEmpty()) {
        sortOperationsByMethod(operations);
        resource.setOperations(operations);
        addSectionsForResource(collectInfo, resource);
        collectInfo.addResource(resource);
      } else {
        LOGGER.warning("Resource " + resource.getName() + " has no methods.");
      }
    } else {
      LOGGER.warning("Resource " + resource.getName() + " has no methods.");
    }

    for (IntrospectionHelper helper : introspectionHelper) {
      helper.processResource(resource, sr.getClass());
    }
  }