/**
   * Returns a list of projects that are associated with the specified contact.
   *
   * @param contact The contact instance to look up projects for.
   * @return A list of the appropriate projects or null.
   */
  public List<FreeAgentProject> getProjects(FreeAgentContact contact) {
    if (contact != null && contact.getUrl() != null && !contact.getUrl().isEmpty()) {

      FreeAgentProjectWrapper projectsWrapper =
          freeAgentServiceInstance.getProjectsForContact(contact.getUrl());
      if (projectsWrapper != null) {
        return projectsWrapper.getProjects();
      }
    }
    return null;
  }
  /**
   * Attempts to import a new contact into the associated FreeAgent account by deserialising the
   * specified JSON contact information and requesting a new contact be created.
   *
   * <p>NOTE: The import (creation within FreeAgent) will only be actioned if no URL property is
   * present or if the URL property is not populated. Otherwise null will be returned.
   *
   * @param contactJSON A string containing contact information in FreeAgent friendly format.
   * @return The newly populated contact instance that has been imported into FreeAgent or null.
   * @throws JsonSyntaxException If the format does not match the FreeAgent V2 Contact format.
   */
  public FreeAgentContact importContact(String contactJSON) throws JsonSyntaxException {
    if (contactJSON == null || contactJSON.isEmpty()) {
      return null;
    }

    FreeAgentContact contact = buildContact(contactJSON);

    if (contact != null && (contact.getUrl() == null || contact.getUrl().isEmpty())) {
      FreeAgentContactWrapper contactWrapper =
          freeAgentServiceInstance.createContact(new FreeAgentContactWrapper(contact));

      if (contactWrapper != null) {
        return contactWrapper.getContact();
      }
    }

    return null;
  }
  /**
   * Attempts to delete the specified contact entry in the associated FreeAgent account.
   *
   * @param contact The populated contact instance.
   * @return True if the contact has been deleted successfully, otherwise false.
   */
  public boolean deleteContact(FreeAgentContact contact) {
    if (contact != null) {
      String contactId = extractIdentifier(contact.getUrl());

      if (contactId != null && !contactId.isEmpty()) {
        Response response = freeAgentServiceInstance.deleteContact(contactId);

        if (response.getStatus() == 200) {
          return true;
        } else {
          return false;
        }
      }
    }
    return false;
  }
  /**
   * Attempts to update the specified contact entry in the associated FreeAgent account.
   *
   * @param contact The populated contact instance.
   * @return True if the contact has been updated successfully, otherwise false.
   */
  public boolean updateContact(FreeAgentContact contact) {
    if (contact != null) {
      String contactId = extractIdentifier(contact.getUrl());

      if (contactId != null && !contactId.isEmpty()) {
        Response response =
            freeAgentServiceInstance.updateContact(new FreeAgentContactWrapper(contact), contactId);
        if (response.getStatus() == 200) {
          contact.setUpdatedAt(dateFormat.format(new Date()));
          return true;
        } else {
          return false;
        }
      }
    }
    return false;
  }