public RegistryObjectType createRegistryObjectVersion(RegistryObjectType ro)
      throws RegistryException {
    RegistryObjectType roNew = null;

    try {
      Utility util = Utility.getInstance();

      RegistryObjectType lastVersion = getLatestVersionOfRegistryObject(ro);
      String nextVersion = null;
      if (lastVersion == null) {
        nextVersion = "1.1";
      } else {
        nextVersion = nextVersion(lastVersion.getVersionInfo().getVersionName());
      }

      roNew = bu.cloneRegistryObject(ro);
      VersionInfoType nextVersionInfo = bu.rimFac.createVersionInfoType();
      nextVersionInfo.setVersionName(nextVersion);

      // Set the comment from the request comment (per the spec)
      if (!context.getRegistryRequestStack().empty()) {
        nextVersionInfo.setComment(context.getCurrentRegistryRequest().getComment());
      }

      roNew.setVersionInfo(nextVersionInfo);

      // A new version must have a unique id
      String id = ro.getId();
      String lid = ro.getLid();
      String idNew = id;

      // Only change id if it already exists in versions
      // Need to preserve client supplied id in the case where lid is an
      // existing lid but id is new
      if (isIdInVersions(id)) {
        // Make id of next version be lid with ":nextVersion" as suffix, if this id is already in
        // use in a version
        idNew = lid + ":" + nextVersion; // Utility.getInstance().createId();
        roNew.setId(idNew);

        // Add entry to idMap so old id and refs to it are mapped to idNew
        context.getIdMap().put(id, idNew);
      }

      // Add entry to context.newROVersionMap for later replacement
      context.getNewROVersionMap().put(ro, roNew);

      // Assign new ids to all composed RegistryObjects within roNew
      Set composedObjects = bu.getComposedRegistryObjects(roNew, -1);

      Iterator iter = composedObjects.iterator();
      while (iter.hasNext()) {
        RegistryObjectType composedObject = (RegistryObjectType) iter.next();

        // check for composed object if exist change the id and lid and
        // also update the idMap.
        if (objectExists(composedObject.getId())) {
          String oldId = composedObject.getId();
          String newId = oldId + ":" + nextVersion;
          composedObject.setId(newId);
          composedObject.setLid(newId);
          context.getIdMap().put(oldId, newId);
        }

        String composedId = composedObject.getId();
        String composedLid = composedObject.getLid();
        String composedIdNew = composedId;

        if (!util.isValidRegistryId(composedId)) { // Replace the id if it's not a valid ID already
          composedIdNew = util.createId();

          composedObject.setId(composedIdNew);

          // Add entry to idMap so old composedId and refs to it are mapped to composedIdNew
          context.getIdMap().put(composedId, composedIdNew);
        }

        if (composedLid == null || composedLid.trim().length() == 0) {
          composedObject.setLid(composedIdNew);
        }
        // Set the parent id of this composed object to point to the new parent
        bu.setParentIdForComposedObject(composedObject, idNew);
      }
    } catch (JAXRException e) {
      throw new RegistryException(e);
    } catch (JAXBException e) {
      throw new RegistryException(e);
    }
    return roNew;
  }
  public boolean needToVersionRegistryObject(RegistryObjectType ro) throws RegistryException {
    boolean needToVersion = true;

    BindingUtility bu = BindingUtility.getInstance();
    boolean newObject = false;

    try {
      needToVersion = isVersionableClass(ro);

      if (needToVersion) {
        HashMap slotsMap;
        // Honour dontVersion flag if specified on request
        if (!context.getRegistryRequestStack().empty()) {
          slotsMap = bu.getSlotsFromRequest(context.getCurrentRegistryRequest());
          if (slotsMap.containsKey(bu.CANONICAL_SLOT_LCM_DONT_VERSION)) {
            String val = (String) slotsMap.get(bu.CANONICAL_SLOT_LCM_DONT_VERSION);
            if (val.trim().equalsIgnoreCase("true")) {
              needToVersion = false;
            }
          }
        }

        // Honour dontVersion flag if specified on ro
        slotsMap = bu.getSlotsFromRegistryObject(ro);
        if (slotsMap.containsKey(bu.CANONICAL_SLOT_LCM_DONT_VERSION)) {
          String val = (String) slotsMap.get(bu.CANONICAL_SLOT_LCM_DONT_VERSION);
          if (val.trim().equalsIgnoreCase("true")) {
            needToVersion = false;
          }
        }
      }

      // TODO:
      // Need to investigate case where not versioning and it is a new object.
      // Need unit test for this case.
      if (needToVersion) {
        versions = getAllRegistryObjectVersions(ro);

        if (versions.size()
            == 0) { // If there are any existing versions (ie. ro's with same LID) then we need to
          // version
          // This is a new ro and therefor need not be versioned
          needToVersion = false;
          newObject = true;
        }
      }

      // Must set versionName to match latest versionName if existing object
      // or set to version 1.1 if new object.
      if (!needToVersion) {
        RegistryObjectType lastVersion = getLatestVersionOfRegistryObject(ro);
        String versionName = null;
        if (lastVersion == null) {
          versionName = "1.1";
        } else {
          versionName = lastVersion.getVersionInfo().getVersionName();

          // Must bump up versionName for new objects
          if (newObject) {
            versionName = nextVersion(versionName);
          }
        }

        VersionInfoType versionInfo = ro.getVersionInfo();
        if (versionInfo == null) {
          versionInfo = bu.rimFac.createVersionInfoType();
          ro.setVersionInfo(versionInfo);
        }
        versionInfo.setVersionName(versionName);
        if (!context.getRegistryRequestStack().empty()) {
          setVersionInfoComment(versionInfo);
        }
      }
    } catch (JAXBException e) {
      throw new RegistryException(e);
    }

    return needToVersion;
  }
  public boolean needToVersionRepositoryItem(ExtrinsicObjectType eo, RepositoryItem riNew)
      throws RegistryException {
    boolean needToVersion = true;

    try {
      // dontVersion eo imples dontVersion ro
      needToVersion = needToVersionRegistryObject(eo);

      if (needToVersion) {
        // This is an existing object not a newly submitted object
        // See if repository item has changed or not.
        HashMap slotsMap;

        // Honour dontVersion flag if specified on request
        if (!context.getRegistryRequestStack().empty()) {
          slotsMap = bu.getSlotsFromRequest(context.getCurrentRegistryRequest());
          if (slotsMap.containsKey(bu.CANONICAL_SLOT_LCM_DONT_VERSION_CONTENT)) {
            String val = (String) slotsMap.get(bu.CANONICAL_SLOT_LCM_DONT_VERSION_CONTENT);
            if (val.trim().equalsIgnoreCase("true")) {
              needToVersion = false;
            }
          }
        }

        // Honour dontVersion flag if specified on ro
        slotsMap = bu.getSlotsFromRegistryObject(eo);
        if (slotsMap.containsKey(bu.CANONICAL_SLOT_LCM_DONT_VERSION_CONTENT)) {
          String val = (String) slotsMap.get(bu.CANONICAL_SLOT_LCM_DONT_VERSION_CONTENT);
          if (val.trim().equalsIgnoreCase("true")) {
            needToVersion = false;
          }
        }
      }

      if (needToVersion) {
        if (riNew == null) {
          needToVersion = false;
          return needToVersion;
        } else {
          RepositoryItem riOld = null;

          try {
            riOld = rm.getRepositoryItem(eo.getId());
          } catch (RepositoryItemNotFoundException e) {
            // It is possible that there is no RepositoryItem yet.
            // Ignore the exception.
          } catch (ObjectNotFoundException e) {
            // It is possible that there is no RepositoryItem yet.
            // Ignore the exception.
          }

          if (riOld == null) {
            needToVersion = false;
          } else {
            if (repositoryItemsAreIdentical(riOld, riNew)) {
              needToVersion = false;
            }
          }
        }
      }

      // Must set contentVersionName to match latest versionName if existing object
      // or set to version 1.1 if new object.
      if (!needToVersion) {
        ExtrinsicObjectType lastVersion =
            (ExtrinsicObjectType) getLatestVersionOfRegistryObject(eo);

        VersionInfoType contentVersionInfo = eo.getContentVersionInfo();
        if (contentVersionInfo == null) {
          contentVersionInfo = bu.rimFac.createVersionInfoType();
        }

        if (lastVersion == null) {
          // This is the first ExtrinsicObject version.
          if (riNew != null) {
            // This is the first RepositoryItem version. Make sure versionName is "1.1"
            contentVersionInfo.setVersionName("1.1");
          } else {
            // No repository item means that the contentVersionInfo MUST be set to null
            contentVersionInfo = null;
          }
        } else {
          // This is not the first ExtrinsicObject version.
          // Note that contentversionName is set even if no RI is submitted since
          // it is OK to update just the EO and have new version use last version of RO

          VersionInfoType lastContentVersionInfo = lastVersion.getContentVersionInfo();

          if (lastContentVersionInfo == null) {
            // Previous version had no repository item
            String lastContentVersionName = rm.getLatestVersionName(context, eo.getLid());
            if (lastContentVersionName != null) {
              contentVersionInfo.setVersionName(lastContentVersionName);
            } else {
              contentVersionInfo.setVersionName("1.1");
            }
          } else {
            // Previous version had a repository item
            // Use the last contentVersionName
            contentVersionInfo.setVersionName(lastContentVersionInfo.getVersionName());
          }
        }
        eo.setContentVersionInfo(contentVersionInfo);
      }

    } catch (JAXBException e) {
      throw new RegistryException(e);
    }

    return needToVersion;
  }