docs: protected ApiVersionBean createApiVersionInternal(NewApiVersionBean bean,
              ApiBean api, GatewaySummaryBean gateway) throws Exception, StorageException {
          if (!BeanUtils.isValidVersion(bean.getVersion())) {
              throw new StorageException("Invalid/illegal API version: " + bean.getVersion()); //$NON-NLS-1$
          }
  
          ApiVersionBean newVersion = new ApiVersionBean();
          newVersion.setVersion(bean.getVersion());
          newVersion.setCreatedBy(securityContext.getCurrentUser());
          newVersion.setCreatedOn(new Date());
          newVersion.setModifiedBy(securityContext.getCurrentUser());
          newVersion.setModifiedOn(new Date());
          newVersion.setStatus(ApiStatus.Created);
          newVersion.setApi(api);
          newVersion.setEndpoint(bean.getEndpoint());
          newVersion.setEndpointType(bean.getEndpointType());
          newVersion.setEndpointContentType(bean.getEndpointContentType());
          if (bean.getPublicAPI() != null) {
              newVersion.setPublicAPI(bean.getPublicAPI());
          }
          if (bean.getParsePayload() != null) {
              newVersion.setParsePayload(bean.getParsePayload());
          }
          if (bean.getPlans() != null) {
              newVersion.setPlans(bean.getPlans());
          }
          if (bean.getDefinitionType() != null) {
              newVersion.setDefinitionType(bean.getDefinitionType());
          }
  
          if (gateway != null && newVersion.getGateways() == null) {
              newVersion.setGateways(new HashSet<>());
              ApiGatewayBean sgb = new ApiGatewayBean();
              sgb.setGatewayId(gateway.getId());
              newVersion.getGateways().add(sgb);
          }
  
          if (apiValidator.isReady(newVersion)) {
              newVersion.setStatus(ApiStatus.Ready);
          } else {
              newVersion.setStatus(ApiStatus.Created);
          }
  
          // Ensure all of the plans are in the right status (locked)
          Set<ApiPlanBean> plans = newVersion.getPlans();
          if (plans != null) {
              for (ApiPlanBean splanBean : plans) {
                  String orgId = newVersion.getApi().getOrganization().getId();
                  PlanVersionBean pvb = storage.getPlanVersion(orgId, splanBean.getPlanId(), splanBean.getVersion());
                  if (pvb == null) {
                      throw new StorageException(Messages.i18n.format("PlanVersionDoesNotExist", splanBean.getPlanId(), splanBean.getVersion())); //$NON-NLS-1$
                  }
                  if (pvb.getStatus() != PlanStatus.Locked) {
                      throw new StorageException(Messages.i18n.format("PlanNotLocked", splanBean.getPlanId(), splanBean.getVersion())); //$NON-NLS-1$
                  }
              }
          }
  
          storage.createApiVersion(newVersion);
          storage.createAuditEntry(AuditUtils.apiVersionCreated(newVersion, securityContext));
  
          if (bean.getDefinitionUrl() != null) {
              InputStream definition = null;
              try {
                  definition = new URL(bean.getDefinitionUrl()).openStream();
                  storage.updateApiDefinition(newVersion, definition);
              } catch (Exception e) {
                  log.error("Unable to store API definition from: " + bean.getDefinitionUrl(), e); //$NON-NLS-1$
              } finally {
                  IOUtils.closeQuietly(definition);
              }
          }
  
          return newVersion;
      }