@Test
  public void testStoreCodeSystemInvalidCyclicLoop() {
    CodeSystem codeSystem = new CodeSystem();
    codeSystem.setUrl(CS_URL);
    codeSystem.setContent(CodeSystemContentMode.NOTPRESENT);
    IIdType id =
        myCodeSystemDao.create(codeSystem, new ServletRequestDetails()).getId().toUnqualified();

    ResourceTable table = myResourceTableDao.findOne(id.getIdPartAsLong());

    TermCodeSystemVersion cs = new TermCodeSystemVersion();
    cs.setResource(table);
    cs.setResourceVersionId(table.getVersion());

    TermConcept parent = new TermConcept();
    parent.setCodeSystem(cs);
    parent.setCode("parent");
    cs.getConcepts().add(parent);

    TermConcept child = new TermConcept();
    child.setCodeSystem(cs);
    child.setCode("child");
    parent.addChild(child, RelationshipTypeEnum.ISA);

    child.addChild(parent, RelationshipTypeEnum.ISA);

    try {
      myTermSvc.storeNewCodeSystemVersion(table.getId(), "http://foo", cs);
      fail();
    } catch (InvalidRequestException e) {
      assertEquals("CodeSystem contains circular reference around code parent", e.getMessage());
    }
  }
  @Override
  public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException {
    IIdType idDt = (IIdType) theArgs[getIdParameterIndex()];
    if (idDt == null) {
      throw new NullPointerException("ID can not be null");
    }

    if (idDt.hasResourceType() == false) {
      idDt = idDt.withResourceType(getResourceName());
    } else if (getResourceName().equals(idDt.getResourceType()) == false) {
      throw new InvalidRequestException(
          "ID parameter has the wrong resource type, expected '"
              + getResourceName()
              + "', found: "
              + idDt.getResourceType());
    }

    HttpDeleteClientInvocation retVal = createDeleteInvocation(getContext(), idDt);

    for (int idx = 0; idx < theArgs.length; idx++) {
      IParameter nextParam = getParameters().get(idx);
      nextParam.translateClientArgumentIntoQueryArgument(getContext(), theArgs[idx], null, null);
    }

    return retVal;
  }
  private IIdType createCodeSystem() {
    CodeSystem codeSystem = new CodeSystem();
    codeSystem.setUrl(CS_URL);
    codeSystem.setContent(CodeSystemContentMode.NOTPRESENT);
    IIdType id =
        myCodeSystemDao.create(codeSystem, new ServletRequestDetails()).getId().toUnqualified();

    ResourceTable table = myResourceTableDao.findOne(id.getIdPartAsLong());

    TermCodeSystemVersion cs = new TermCodeSystemVersion();
    cs.setResource(table);
    cs.setResourceVersionId(table.getVersion());

    TermConcept parentA = new TermConcept(cs, "ParentA");
    cs.getConcepts().add(parentA);

    TermConcept childAA = new TermConcept(cs, "childAA");
    parentA.addChild(childAA, RelationshipTypeEnum.ISA);

    TermConcept childAAA = new TermConcept(cs, "childAAA");
    childAA.addChild(childAAA, RelationshipTypeEnum.ISA);

    TermConcept childAAB = new TermConcept(cs, "childAAB");
    childAA.addChild(childAAB, RelationshipTypeEnum.ISA);

    TermConcept childAB = new TermConcept(cs, "childAB");
    parentA.addChild(childAB, RelationshipTypeEnum.ISA);

    TermConcept parentB = new TermConcept(cs, "ParentB");
    cs.getConcepts().add(parentB);

    myTermSvc.storeNewCodeSystemVersion(table.getId(), "http://foo", cs);
    return id;
  }
  protected static void parseContentLocation(
      FhirContext theContext, MethodOutcome theOutcomeToPopulate, String theLocationHeader) {
    if (StringUtils.isBlank(theLocationHeader)) {
      return;
    }

    IIdType id = theContext.getVersion().newIdType();
    id.setValue(theLocationHeader);
    theOutcomeToPopulate.setId(id);
  }
  @Test
  public void testCreateDuplicateCodeSystemUri() {
    CodeSystem codeSystem = new CodeSystem();
    codeSystem.setUrl(CS_URL);
    codeSystem.setContent(CodeSystemContentMode.NOTPRESENT);
    IIdType id =
        myCodeSystemDao.create(codeSystem, new ServletRequestDetails()).getId().toUnqualified();

    ResourceTable table = myResourceTableDao.findOne(id.getIdPartAsLong());

    TermCodeSystemVersion cs = new TermCodeSystemVersion();
    cs.setResource(table);
    cs.setResourceVersionId(table.getVersion());

    myTermSvc.storeNewCodeSystemVersion(table.getId(), CS_URL, cs);

    // Update
    cs = new TermCodeSystemVersion();
    TermConcept parentA = new TermConcept(cs, "ParentA");
    cs.getConcepts().add(parentA);
    id = myCodeSystemDao.update(codeSystem, new ServletRequestDetails()).getId().toUnqualified();
    table = myResourceTableDao.findOne(id.getIdPartAsLong());
    cs.setResource(table);
    cs.setResourceVersionId(table.getVersion());
    myTermSvc.storeNewCodeSystemVersion(table.getId(), CS_URL, cs);

    // Try to update to a different resource
    codeSystem = new CodeSystem();
    codeSystem.setUrl(CS_URL);
    codeSystem.setContent(CodeSystemContentMode.NOTPRESENT);
    id = myCodeSystemDao.create(codeSystem, new ServletRequestDetails()).getId().toUnqualified();
    table = myResourceTableDao.findOne(id.getIdPartAsLong());
    cs.setResource(table);
    cs.setResourceVersionId(table.getVersion());
    try {
      myTermSvc.storeNewCodeSystemVersion(table.getId(), CS_URL, cs);
      fail();
    } catch (UnprocessableEntityException e) {
      assertThat(
          e.getMessage(),
          containsString(
              "Can not create multiple code systems with URI \"http://example.com/my_code_system\", already have one with resource ID: CodeSystem/"));
    }
  }
  @Test
  public void testFindCodesBelowA() {
    IIdType id = createCodeSystem();

    Set<TermConcept> concepts;
    Set<String> codes;

    concepts =
        myTermSvc.findCodesBelow(id.getIdPartAsLong(), id.getVersionIdPartAsLong(), "ParentA");
    codes = toCodes(concepts);
    assertThat(codes, containsInAnyOrder("ParentA", "childAA", "childAAA", "childAAB", "childAB"));

    concepts =
        myTermSvc.findCodesBelow(id.getIdPartAsLong(), id.getVersionIdPartAsLong(), "childAA");
    codes = toCodes(concepts);
    assertThat(codes, containsInAnyOrder("childAA", "childAAA", "childAAB"));

    // Try an unknown code
    concepts =
        myTermSvc.findCodesBelow(id.getIdPartAsLong(), id.getVersionIdPartAsLong(), "FOO_BAD_CODE");
    codes = toCodes(concepts);
    assertThat(codes, empty());
  }
  private Object returnResponse(
      IRestfulServer<?> theServer,
      RequestDetails theRequest,
      MethodOutcome response,
      IBaseResource originalOutcome,
      IBaseResource resource)
      throws IOException {
    boolean allowPrefer = false;
    int operationStatus = getOperationStatus(response);
    IBaseResource outcome = originalOutcome;

    if (ourOperationsWhichAllowPreferHeader.contains(getRestOperationType())) {
      allowPrefer = true;
    }

    if (resource != null && allowPrefer) {
      String prefer = theRequest.getHeader(Constants.HEADER_PREFER);
      PreferReturnEnum preferReturn = RestfulServerUtils.parsePreferHeader(prefer);
      if (preferReturn != null) {
        if (preferReturn == PreferReturnEnum.REPRESENTATION) {
          outcome = resource;
        }
      }
    }

    for (int i = theServer.getInterceptors().size() - 1; i >= 0; i--) {
      IServerInterceptor next = theServer.getInterceptors().get(i);
      boolean continueProcessing = next.outgoingResponse(theRequest, outcome);
      if (!continueProcessing) {
        return null;
      }
    }

    IRestfulResponse restfulResponse = theRequest.getResponse();

    if (response != null) {
      if (response.getResource() != null) {
        restfulResponse.setOperationResourceLastUpdated(
            RestfulServerUtils.extractLastUpdatedFromResource(response.getResource()));
      }

      IIdType responseId = response.getId();
      if (responseId != null && responseId.getResourceType() == null && responseId.hasIdPart()) {
        responseId = responseId.withResourceType(getResourceName());
      }

      if (responseId != null) {
        String serverBase = theRequest.getFhirServerBase();
        responseId =
            RestfulServerUtils.fullyQualifyResourceIdOrReturnNull(
                theServer, resource, serverBase, responseId);
        restfulResponse.setOperationResourceId(responseId);
      }
    }

    boolean prettyPrint = RestfulServerUtils.prettyPrintResponse(theServer, theRequest);
    Set<SummaryEnum> summaryMode = Collections.emptySet();

    return restfulResponse.streamResponseAsResource(
        outcome, prettyPrint, summaryMode, operationStatus, null, theRequest.isRespondGzip(), true);
    //		return theRequest.getResponse().returnResponse(ParseAction.create(outcome), operationStatus,
    // allowPrefer, response, getResourceName());
  }