/**
  * Returns a list of all the known contacts contained within FreeAgent for the authorised account.
  *
  * @return A list of Contact instances.
  */
 public List<FreeAgentContact> getContacts() {
   FreeAgentContactWrapper contactsWrapper = freeAgentServiceInstance.getContacts();
   if (contactsWrapper != null) {
     return contactsWrapper.getContacts();
   }
   return null;
 }
 /**
  * Returns a list of all the known contacts contained within FreeAgentService for the authorised
  * account.
  *
  * @param viewType The view type {@link
  *     com.karlnosworthy.freeagent.FreeAgentClient.ContactViewType} filter to apply to the
  *     contacts
  * @return A list of Contact instances.
  */
 public List<FreeAgentContact> getContacts(ContactViewType viewType) {
   FreeAgentContactWrapper contactsWrapper =
       freeAgentServiceInstance.getContacts(viewType.identifier);
   if (contactsWrapper != null) {
     return contactsWrapper.getContacts();
   }
   return null;
 }
  /**
   * Returns a list of all the known users contained within FreeAgent for the authorised account.
   *
   * @return A list of User instances.
   */
  public List<FreeAgentUser> getUsers() {
    FreeAgentUserWrapper usersWrapper = freeAgentServiceInstance.getUsers();

    if (usersWrapper != null) {
      return usersWrapper.getUsers();
    }
    return null;
  }
  /**
   * Returns the basic information about the company contained within FreeAgent for the authorised
   * account.
   *
   * @return A populated FreeAgentCompany instance or null.
   */
  public FreeAgentCompany getCompany() {
    FreeAgentCompanyWrapper companyWrapper = freeAgentServiceInstance.getCompany();

    if (companyWrapper != null) {
      return companyWrapper.getCompany();
    }
    return null;
  }
  /**
   * Returns a list of all the known projects contained within FreeAgent for the authorised account.
   *
   * @return A list of Project instances.
   */
  public List<FreeAgentProject> getProjects() {
    FreeAgentProjectWrapper projectsWrapper = freeAgentServiceInstance.getProjects();

    if (projectsWrapper != null) {
      return projectsWrapper.getProjects();
    }
    return null;
  }
  /**
   * Retrieves the information about the current user/personal profile contained within the
   * FreeAgent authorised account.
   *
   * @return The current user/personal profile or null if the profile could not be obtained.
   */
  public FreeAgentUser getPersonalProfile() {
    FreeAgentUserWrapper userWrapper = freeAgentServiceInstance.getCurrentUser();

    if (userWrapper != null) {
      return userWrapper.getUser();
    }
    return null;
  }
 /**
  * Retrieves the users that matches the specified id.
  *
  * @param userId The id to match.
  * @return A User instance or null if the id supplied was invalid or could not be matched.
  */
 public FreeAgentUser getUser(String userId) {
   if (userId != null && !userId.isEmpty()) {
     FreeAgentUserWrapper userWrapper = freeAgentServiceInstance.getUser(userId);
     if (userWrapper != null) {
       return userWrapper.getUser();
     }
   }
   return null;
 }
 /**
  * Retrieves the invoice that matches the specified id.
  *
  * @param invoiceId The id to match.
  * @return An Invoice instance or null if the id supplied was invalid or could not be matched.
  */
 public FreeAgentInvoice getInvoice(String invoiceId) {
   if (invoiceId != null && !invoiceId.isEmpty()) {
     FreeAgentInvoiceWrapper invoiceWrapper = freeAgentServiceInstance.getInvoice(invoiceId);
     if (invoiceWrapper != null) {
       return invoiceWrapper.getInvoice();
     }
   }
   return null;
 }
  /**
   * Returns a list of all the known projects contained within FreeAgent for the authorised account.
   *
   * @param statusType The view type {@link
   *     com.karlnosworthy.freeagent.FreeAgentClient.ProjectStatusType} filter to apply to the
   *     projects.
   * @return A list of Project instances.
   */
  public List<FreeAgentProject> getProjects(ProjectStatusType statusType) {
    FreeAgentProjectWrapper projectsWrapper =
        freeAgentServiceInstance.getProjects(statusType.identifier);

    if (projectsWrapper != null) {
      return projectsWrapper.getProjects();
    }
    return null;
  }
 /**
  * Retrieves the contact that matches the specified id.
  *
  * @param contactId The id to match.
  * @return A Contact instance or null if the id supplied was invalid or could not be matched.
  */
 public FreeAgentContact getContact(String contactId) {
   if (contactId != null && !contactId.isEmpty()) {
     FreeAgentContactWrapper contactWrapper = freeAgentServiceInstance.getContact(contactId);
     if (contactWrapper != null) {
       return contactWrapper.getContact();
     }
   }
   return null;
 }
  /**
   * Retrieves the project that matches the specified id.
   *
   * @param projectId The id to match.
   * @return A Project instance or null if the id supplied was invalid or could not be matched.
   */
  public FreeAgentProject getProject(String projectId) {
    if (projectId != null && !projectId.isEmpty()) {
      FreeAgentProjectWrapper projectWrapper = freeAgentServiceInstance.getProject(projectId);

      if (projectWrapper != null) {
        return projectWrapper.getProject();
      }
    }
    return null;
  }
 /**
  * Attempts to create a new user entry in the associated FreeAgent account.
  *
  * <p>Will return null if the user instance provided is null or cannot be saved into the account.
  *
  * @param user The populated user instance.
  * @return The updated user instance or null.
  */
 public FreeAgentUser createUser(FreeAgentUser user) {
   if (user != null) {
     FreeAgentUserWrapper userWrapper =
         freeAgentServiceInstance.createUser(new FreeAgentUserWrapper(user));
     if (userWrapper != null) {
       return userWrapper.getUser();
     }
   }
   return null;
 }
 /**
  * Attempts to create a new project entry in the associated FreeAgent account.
  *
  * <p>Will return null if the project instance provided is null or cannot be saved into the
  * account.
  *
  * @param project The populated project instance.
  * @return The updated project instance or null.
  */
 public FreeAgentProject createProject(FreeAgentProject project) {
   if (project != null) {
     FreeAgentProjectWrapper projectWrapper =
         freeAgentServiceInstance.createProject(new FreeAgentProjectWrapper(project));
     if (projectWrapper != null) {
       return projectWrapper.getProject();
     }
   }
   return null;
 }
 /**
  * Attempts to create a new invoice entry in the associated FreeAgent account.
  *
  * <p>Will return null if the invoice instance provided is null or cannot be saved into the
  * account.
  *
  * @param invoice The populated invoice instance.
  * @return The updated invoice instance or null.
  */
 public FreeAgentInvoice createInvoice(FreeAgentInvoice invoice) {
   if (invoice != null) {
     FreeAgentInvoiceWrapper invoiceWrapper =
         freeAgentServiceInstance.createInvoice(new FreeAgentInvoiceWrapper(invoice));
     if (invoiceWrapper != null) {
       return invoiceWrapper.getInvoice();
     }
   }
   return null;
 }
 /**
  * Attempts to create a new contact entry in the associated FreeAgent account.
  *
  * <p>Will return null if the contact instance provided is null or cannot be saved into the
  * account.
  *
  * @param contact The populated contact instance.
  * @return The updated contact instance or null.
  */
 public FreeAgentContact createContact(FreeAgentContact contact) {
   if (contact != null) {
     FreeAgentContactWrapper contactWrapper =
         freeAgentServiceInstance.createContact(new FreeAgentContactWrapper(contact));
     if (contactWrapper != null) {
       return contactWrapper.getContact();
     }
   }
   return null;
 }
  /**
   * Returns a list of the invoices contained within FreeAgent for the authorised account.
   *
   * @param nestInvoiceItems Should the invoice items also be included with the invoice
   * @return A list of FreeAgentInvoice instances.
   */
  public List<FreeAgentInvoice> getInvoices(boolean nestInvoiceItems) {
    FreeAgentInvoiceWrapper invoicesWrapper =
        freeAgentServiceInstance.getInvoices(nestInvoiceItems);

    if (invoicesWrapper != null && invoicesWrapper.hasInvoices()) {
      return invoicesWrapper.getInvoices();
    } else {
      return null;
    }
  }
  /**
   * 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;
  }
  /**
   * Retrieves the Contact associated with the specified project.
   *
   * @param project The populated project instance to retrieve the contact for.
   * @return A populated FreeAgentContact instance or null if the contact could not be found.
   */
  public FreeAgentContact getContactForProject(FreeAgentProject project) {
    if (project != null) {
      String contactId = extractIdentifier(project.getContact());

      if (contactId != null && !contactId.isEmpty()) {
        FreeAgentContactWrapper contactWrapper = freeAgentServiceInstance.getContact(contactId);

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

      if (invoiceId != null && !invoiceId.isEmpty()) {
        Response response = freeAgentServiceInstance.deleteInvoice(invoiceId);

        if (response.getStatus() == 200) {
          return true;
        } else {
          return false;
        }
      }
    }
    return false;
  }
  /**
   * Attempts to delete the specified project entry in the associated FreeAgent account.
   *
   * @param project The populated project instance.
   * @return True if the project has been deleted successfully, otherwise false.
   */
  public boolean deleteProject(FreeAgentProject project) {
    if (project != null) {
      String projectId = extractIdentifier(project.getUrl());

      if (projectId != null && !projectId.isEmpty()) {
        Response response = freeAgentServiceInstance.deleteProject(projectId);

        if (response.getStatus() == 200) {
          return true;
        } else {
          return false;
        }
      }
    }
    return false;
  }
  /**
   * Attempts to delete the specified user entry in the associated FreeAgent account.
   *
   * @param user The populated user instance.
   * @return True if the user has been deleted successfully, otherwise false.
   */
  public boolean deleteUser(FreeAgentUser user) {
    if (user != null) {
      String userId = extractIdentifier(user.getUrl());

      if (userId != null && !userId.isEmpty()) {
        Response response = freeAgentServiceInstance.deleteUser(userId);

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

      if (invoiceId != null && !invoiceId.isEmpty()) {
        Response response =
            freeAgentServiceInstance.updateInvoice(new FreeAgentInvoiceWrapper(invoice), invoiceId);
        if (response.getStatus() == 200) {
          invoice.setUpdatedAt(dateFormat.format(new Date()));
          return true;
        } else {
          return false;
        }
      }
    }
    return false;
  }
  /**
   * Attempts to update the specified project entry in the associated FreeAgent account.
   *
   * @param project The populated project instance.
   * @return True if the project has been updated successfully, otherwise false.
   */
  public boolean updateProject(FreeAgentProject project) {
    if (project != null) {
      String projectId = extractIdentifier(project.getUrl());

      if (projectId != null && !projectId.isEmpty()) {
        Response response =
            freeAgentServiceInstance.updateProject(new FreeAgentProjectWrapper(project), projectId);
        if (response.getStatus() == 200) {
          project.setUpdatedAt(dateFormat.format(new Date()));
          return true;
        } else {
          return false;
        }
      }
    }
    return false;
  }
  /**
   * Attempts to import a new user into the associated FreeAgent account by deserialising the
   * specified JSON user information and requesting a new user 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 userJSON A string containing user information in FreeAgent friendly format.
   * @return The newly populated user instance that has been imported into FreeAgent or null.
   * @throws JsonSyntaxException If the format does not match the FreeAgent V2 User format.
   */
  public FreeAgentUser importUser(String userJSON) throws JsonSyntaxException {
    if (userJSON == null || userJSON.isEmpty()) {
      return null;
    }

    FreeAgentUser user = buildUser(userJSON);

    if (user != null && (user.getUrl() == null || user.getUrl().isEmpty())) {
      FreeAgentUserWrapper userWrapper =
          freeAgentServiceInstance.createUser(new FreeAgentUserWrapper(user));

      if (userWrapper != null) {
        return userWrapper.getUser();
      }
    }

    return null;
  }
  /**
   * Attempts to import a new project into the associated FreeAgent account by deserialising the
   * specified JSON project information and requesting a new project 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 projectJSON A string containing project information in FreeAgent friendly format.
   * @return The newly populated project instance that has been imported into FreeAgent or null.
   * @throws JsonSyntaxException If the format does not match the FreeAgent V2 Project format.
   */
  public FreeAgentProject importProject(String projectJSON) throws JsonSyntaxException {
    if (projectJSON == null || projectJSON.isEmpty()) {
      return null;
    }

    FreeAgentProject project = buildProject(projectJSON);

    if (project != null && (project.getUrl() == null || project.getUrl().isEmpty())) {
      FreeAgentProjectWrapper projectWrapper =
          freeAgentServiceInstance.createProject(new FreeAgentProjectWrapper(project));

      if (projectWrapper != null) {
        return projectWrapper.getProject();
      }
    }

    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 import a new invoice into the associated FreeAgent account by deserialising the
   * specified JSON invoice information and requesting a new invoice 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 invoiceJSON A string containing invoice information in FreeAgent friendly format.
   * @return The newly populated invoice instance that has been imported into FreeAgent or null.
   * @throws JsonSyntaxException If the format does not match the FreeAgent V2 Invoice format.
   */
  public FreeAgentInvoice importInvoice(String invoiceJSON) throws JsonSyntaxException {
    if (invoiceJSON == null || invoiceJSON.isEmpty()) {
      return null;
    }

    FreeAgentInvoice invoice = buildInvoice(invoiceJSON);

    if (invoice != null && (invoice.getUrl() == null || invoice.getUrl().isEmpty())) {
      FreeAgentInvoiceWrapper invoiceWrapper =
          freeAgentServiceInstance.createInvoice(new FreeAgentInvoiceWrapper(invoice));

      if (invoiceWrapper != null) {
        return invoiceWrapper.getInvoice();
      }
    }

    return null;
  }