diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md
index 0f268725c7a..014d3500a1b 100644
--- a/docs/DeveloperGuide.md
+++ b/docs/DeveloperGuide.md
@@ -219,6 +219,48 @@ Pros: Arguably a more OOP approach since all commands that trigger view IS-A `Vi
Cons: You cannot implement any command that does not involve viewing but inherits from any command that is a children of `ViewCommand`.
An example could be trying to create identical commands that does not toggle the UI after execution. This would require duplication of the exact same command code but inheriting from `Command` instead of `ViewCommand`.
+
+### Search feature
+
+#### Implementation
+
+The search feature is implemented using the `SearchCommand` class. It extends `Command` and overrides the `execute()` method to
+filter users by the specified parameters.
+
+The search parameters from the user input are parsed using the parse method in the `SearchCommandParser` class. `SearchCommandParser::Parse`
+takes in the search parameters from the user input and combines them into a list of predicates. This list of predicates is then
+passed as an argument to the `SearchCommand` constructor and the method returns a `SearchCommand` instance with the associated list of predicates.
+
+Currently, the search parameters could belong to any of the three following categories: `Name`, `Status`, and `Tag`. Prefixes
+`n/`, `st/` and `t/` are used to denote the category of the search parameters respectively. E.g. `search n/alex st/interviewed t/swe`
+
+The list of predicates is a list comprising predicate objects whose classes implement the `Predicate` class in Java.
+Each category has its own predicate class i.e. `NameContainsKeywordPredicate`, `StatusContainsKeywordPredicate`, `TagContainsKeywordPredicate`
+and each class overrides the `test` method which returns true if the persons list contains any of the given names/status/tags.
+
+Finally, the execute method in `SearchCommand` class invokes the `updateFilteredPersonList(predicatesList)` which will
+update the list of persons displayed.
+
+Given below is an example usage scenario and how the search mechanism behaves at each step.
+
+Step 1. The user launches the application.
+
+Step 2. The user executes `search n/john st/offered t/swe` command to filter candidates having the name john,
+offered status and tagged as swe.
+
+The following sequence diagram shows how the search operation works:
+
+**Note:** The lifeline for `SearchCommand` and `SearchCommandParser` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
+
+
+
+Step 3. The user should see the UI below upon entering `search n/john st/interviewed t/friends`.
+
+![View](images/search.png)
+
+**Note:** The current implementation of search allows users to search by any of the categories individually or by different combinations of the categories.
+It also allows users to specify more than one search parameter for each category e.g. `search n/alex bernice`
+
### \[Proposed\] Undo/redo feature
#### Proposed Implementation
@@ -432,31 +474,16 @@ Use case ends.
* 2b1. JABPro shows a message indicating that there are no persons to display.
Use case ends.
-**Use case: Search a person by name**
+**Use case: Search persons by the specified categories(name, status and/ tag)**
**MSS**
-1. Hiring manager types in name keywords to search users by name.
-2. JABPro shows a list of persons whose names contain matching keywords.
- Use case ends.
-
-**Extensions**
-
-* 1a. The given name keyword is invalid (invalid name).
- * 1a1. JABPro shows an error message.
- Use case resumes at step 1.
-* 2a. The list is empty.
- Use case ends.
-
-**Use case: Search a person by application status**
-
-**MSS**
-1. User keys in search command with application status (i.e. interviewed, pending, rejected, offered).
-2. JABPro shows a list of persons whose status match the given status keywords.
- Use case ends.
+1. Hiring manager types in search parameters to search users by the specified categories.
+2. JABPro shows a list of persons whose profile matches the given parameters.
+Use case ends.
**Extensions**
-* 1a. The given name status is invalid (not from the given list of valid status keywords).
+* 1a. The given name/status/tag parameter is invalid.
* 1a1. JABPro shows an error message.
Use case resumes at step 1.
* 2a. The list is empty.
diff --git a/docs/UserGuide.md b/docs/UserGuide.md
index b03f8a194cb..c1b8b5b4bae 100644
--- a/docs/UserGuide.md
+++ b/docs/UserGuide.md
@@ -62,6 +62,9 @@ JobApplicationsBook Pro (JABPro) is a **desktop app for hiring managers of compa
* Items in square brackets are optional.
e.g `n/NAME [t/TAG]` can be used as `n/John Doe t/friend` or as `n/John Doe`.
+* When using parentheses ( ) with items separated by the pipe symbol |, at least one item must be included.
+ e.g in the command `search (n/KEYWORD [MORE KEYWORDS] | st/KEYWORD [MORE KEYWORDS] | t/KEYWORD [MORE KEYWORDS])`, it is necessary to specify at least one search category.
+
* Items with `…` after them can be used multiple times including zero times.
e.g. `[t/TAG]…` can be used as ` ` (i.e. 0 times), `t/friend`, `t/friend t/family` etc.
@@ -196,7 +199,9 @@ Examples:
### Search job applicants by category: `search`
-Finds job applicants whose profiles match the specified categories' keywords. The search categories are: name, status
+Finds job applicants whose profiles match the specified categories' keywords. The search categories are: name, status, tag.
+
+Format: `search (n/KEYWORD [MORE KEYWORDS] | st/KEYWORD [MORE KEYWORDS] | t/KEYWORD [MORE KEYWORDS])`
#### Search job applicants by name
@@ -219,24 +224,36 @@ Examples:
Finds job applicants whose status match any of the given keywords
-Format: `search s/KEYWORD [MORE KEYWORDS]`
+Format: `search st/KEYWORD [MORE KEYWORDS]`
+
+* Keywords can only be from the following list: `Preliminary`, `Interviewed`, `Rejected`, `Offered`
+ e.g. `search st/interviewing` will give an error.
+* Keywords are case-insensitive: `search st/interviewed` and `search st/INTERVIEWED` return the same result.
+
+Example:
+* `search st/interviewed`
+
+#### Search job applicants by tag
+
+Finds job applicants whose tag(s) match any of the given tag keywords
+
+Format: `search t/KEYWORD [MORE KEYWORDS]`
-* Keywords can only be from the following list: `Pending`, `Interviewed`, `Rejected`, `Offered`
- e.g. `search s/interviewing` will give an error.
-* Keywords are case-insensitive: `search s/interviewd` and `search s/INTERVIEWED` return the same result.
+* Keywords are case-insensitive: `search t/hardworking' and `search t/HARDWORKING` return the same result.
Example:
-* `search s/interviewed`
+* `search t/hardworking`
#### Notes for advanced users:
-* You can combine the name and status search categories (e.g. `search n/Alex s/offered`) in a single search command.
+* You can combine the search categories (e.g. `search n/Alex st/offered t/software engineer`) in a single search command.
* Each search category can be used at most once in a single search command
- e.g. `search n/Alex n/Adam s/rejected` is not allowed.
+ e.g. `search n/Alex n/Adam st/rejected` is not allowed.
Example:
-* `search n/Alex Bernice s/interviewed rejected` will output applicants whose:
+* `search n/Alex Bernice st/interviewed rejected t/analyst` will output applicants whose:
* names contain either Alex `or` Bernice
* `and` status is either interviewed `or` rejected.
+ * `and` has a tag `analyst`
### Deleting a person : `delete`
@@ -354,7 +371,7 @@ Action | Format, Examples
**Delete** | `delete INDEX`
e.g., `delete 3`
**Set** | `set INDEX STATUS`
e.g., `set 2 Interviewed`
**Edit** | `edit INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [a/ADDRESS] [t/TAG]…`
e.g.,`edit 2 n/James Lee e/jameslee@example.com`
-**Find** | `find KEYWORD [MORE_KEYWORDS]`
e.g., `find James Jake`
+**Search** | `search (n/KEYWORD [MORE KEYWORDS] | st/KEYWORD [MORE KEYWORDS] | t/KEYWORD [MORE KEYWORDS])`
e.g., `search n/alex st/interviewed`
**List** | `list s/ATTRIBUTE`
e.g. `list s/name`
**Export** | `export`
**Help** | `help`
diff --git a/docs/diagrams/SearchSequenceDiagram.puml b/docs/diagrams/SearchSequenceDiagram.puml
new file mode 100644
index 00000000000..37f57208496
--- /dev/null
+++ b/docs/diagrams/SearchSequenceDiagram.puml
@@ -0,0 +1,76 @@
+@startuml
+!include style.puml
+skinparam ArrowFontStyle plain
+
+
+box Logic LOGIC_COLOR_T1
+participant ":LogicManager" as LogicManager LOGIC_COLOR
+participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR
+participant ":SearchCommandParser" as SearchCommandParser LOGIC_COLOR
+participant "f:SearchCommand" as SearchCommand LOGIC_COLOR
+participant ":CommandResult" as CommandResult LOGIC_COLOR
+end box
+
+box Model MODEL_COLOR_T1
+participant ":Model" as Model MODEL_COLOR
+end box
+
+[-> LogicManager : execute("search st/offered")
+activate LogicManager
+
+LogicManager -> AddressBookParser : parseCommand("search st/offered")
+activate AddressBookParser
+
+create SearchCommandParser
+AddressBookParser -> SearchCommandParser
+activate SearchCommandParser
+
+SearchCommandParser --> AddressBookParser
+deactivate SearchCommandParser
+
+AddressBookParser -> SearchCommandParser : parse("search st/offered")
+activate SearchCommandParser
+
+create SearchCommand
+SearchCommandParser -> SearchCommand : searchCommand(predicatesList)
+activate SearchCommand
+
+SearchCommand --> SearchCommandParser : f
+deactivate SearchCommand
+
+SearchCommandParser --> AddressBookParser : f
+deactivate SearchCommandParser
+'Hidden arrow to position the destroy marker below the end of the activation bar.
+SearchCommandParser -[hidden]-> AddressBookParser
+destroy SearchCommandParser
+
+AddressBookParser --> LogicManager : f
+deactivate AddressBookParser
+
+LogicManager -> SearchCommand : execute()
+activate SearchCommand
+
+SearchCommand -> Model : updateFilteredPersonList(predicatesList)
+activate Model
+
+Model --> SearchCommand
+deactivate Model
+
+create CommandResult
+SearchCommand -> CommandResult
+activate CommandResult
+
+CommandResult --> SearchCommand
+deactivate CommandResult
+
+SearchCommand --> LogicManager : result
+deactivate SearchCommand
+
+
+
+[<--LogicManager
+deactivate LogicManager
+
+
+
+@enduml
diff --git a/docs/images/search.png b/docs/images/search.png
new file mode 100644
index 00000000000..6a8c8208602
Binary files /dev/null and b/docs/images/search.png differ