diff --git a/src/main/scala/codecheck/github/api/GitHubAPI.scala b/src/main/scala/codecheck/github/api/GitHubAPI.scala
index 7117afb..0fc1f37 100644
--- a/src/main/scala/codecheck/github/api/GitHubAPI.scala
+++ b/src/main/scala/codecheck/github/api/GitHubAPI.scala
@@ -28,6 +28,7 @@ class GitHubAPI(token: String, client: Transport, tokenType: String = "token", d
   with WebhookOp
   with CollaboratorOp
   with BranchOp
+  with SearchOp
 {
 
   private val endpoint = "https://api.github.com"
diff --git a/src/main/scala/codecheck/github/models/Repository.scala b/src/main/scala/codecheck/github/models/Repository.scala
index 6ec3bc4..c90e5cb 100644
--- a/src/main/scala/codecheck/github/models/Repository.scala
+++ b/src/main/scala/codecheck/github/models/Repository.scala
@@ -66,9 +66,12 @@ case class Repository(value: JValue) extends AbstractJson(value) {
   def name = get("name")
   def full_name = get("full_name")
   def url = get("url")
+  def language = get("language")
+  def stargazers_count = get("stargazers_count").toLong
 
   def description = opt("description")
-  def open_issues_count = get("open_issues_count").toInt
+  def open_issues_count = get("open_issues_count").toLong
+  def `private` = boolean("private")
 
   lazy val permissions = Permissions(value \ "permissions")
   lazy val owner = User(value \ "owner")
diff --git a/src/main/scala/codecheck/github/models/Search.scala b/src/main/scala/codecheck/github/models/Search.scala
new file mode 100644
index 0000000..c5e2d12
--- /dev/null
+++ b/src/main/scala/codecheck/github/models/Search.scala
@@ -0,0 +1,133 @@
+package codecheck.github.models
+
+import org.json4s.JValue
+import org.json4s.JArray
+
+sealed trait SearchSort {
+  def name: String
+  override def toString = name
+}
+
+sealed abstract class SearchRepositorySort(val name: String) extends SearchSort
+
+object SearchRepositorySort {
+  case object stars   extends SearchRepositorySort("stars")
+  case object forks   extends SearchRepositorySort("forks")
+  case object updated extends SearchRepositorySort("updated")
+
+  val values = Array(stars, forks, updated)
+
+  def fromString(str: String) = values.filter(_.name == str).head
+}
+
+sealed abstract class SearchCodeSort(val name: String) extends SearchSort
+
+object SearchCodeSort {
+  case object indexed extends SearchCodeSort("indexed")
+
+  val values = Array(indexed)
+
+  def fromString(str: String) = values.filter(_.name == str).head
+}
+
+sealed abstract class SearchIssueSort(val name: String) extends SearchSort
+
+object SearchIssueSort {
+  case object created  extends SearchIssueSort("created")
+  case object updated  extends SearchIssueSort("updated")
+  case object comments extends SearchIssueSort("comments")
+
+  val values = Array(created, updated, comments)
+
+  def fromString(str: String) = values.filter(_.name == str).head
+}
+
+sealed abstract class SearchUserSort(val name: String) extends SearchSort
+
+object SearchUserSort {
+  case object followers    extends SearchUserSort("followers")
+  case object repositories extends SearchUserSort("repositories")
+  case object joined       extends SearchUserSort("joined")
+
+  val values = Array(followers, repositories, joined)
+
+  def fromString(str: String) = values.filter(_.name == str).head
+}
+
+sealed trait SearchInput extends AbstractInput {
+ def q: String
+ def sort: Option[SearchSort]
+ def order: SortDirection
+ def query = s"?q=$q" + sort.map(sortBy => s"&sort=$sortBy&order=$order").getOrElse("")
+}
+
+case class SearchRepositoryInput (
+ val q: String,
+ val sort: Option[SearchRepositorySort] = None,
+ val order: SortDirection = SortDirection.desc
+) extends SearchInput
+
+case class SearchRepositoryResult(value: JValue) extends AbstractJson(value) {
+ def total_count: Long = get("total_count").toLong
+ def incomplete_results: Boolean = boolean("incomplete_results")
+ lazy val items = (value \ "items") match {
+    case JArray(arr) => arr.map(Repository(_))
+    case _ => Nil
+  }
+}
+
+case class SearchCodeInput (
+ q: String,
+ sort: Option[SearchCodeSort] = None,
+ order: SortDirection = SortDirection.desc
+) extends SearchInput
+
+case class SearchCodeItem(value: JValue) extends AbstractJson(value) {
+  def name: String = get("name")
+  def path: String = get("path")
+  def sha: String = get("sha")
+  def url: String = get("url")
+  def git_url: String = get("git_url")
+  def html_url: String = get("html_url")
+  def score: Double = get("score").toDouble
+  lazy val repository = Repository(value \ "repository")
+}
+
+case class SearchCodeResult(value: JValue) extends AbstractJson(value) {
+ def total_count: Long = get("total_count").toLong
+ def incomplete_results: Boolean = boolean("incomplete_results")
+ lazy val items = (value \ "items") match {
+    case JArray(arr) => arr.map(SearchCodeItem(_))
+    case _ => Nil
+  }
+}
+
+case class SearchIssueInput (
+ q: String,
+ sort: Option[SearchIssueSort] = None,
+ order: SortDirection = SortDirection.desc
+) extends SearchInput
+
+case class SearchIssueResult(value: JValue) extends AbstractJson(value) {
+ def total_count: Long = get("total_count").toLong
+ def incomplete_results: Boolean = boolean("incomplete_results")
+ lazy val items = (value \ "items") match {
+    case JArray(arr) => arr.map(Issue(_))
+    case _ => Nil
+  }
+}
+
+case class SearchUserInput (
+ q: String,
+ sort: Option[SearchUserSort] = None,
+ order: SortDirection = SortDirection.desc
+) extends SearchInput
+
+case class SearchUserResult(value: JValue) extends AbstractJson(value) {
+ def total_count: Long = get("total_count").toLong
+ def incomplete_results: Boolean = boolean("incomplete_results")
+ lazy val items = (value \ "items") match {
+    case JArray(arr) => arr.map(User(_))
+    case _ => Nil
+  }
+}
diff --git a/src/main/scala/codecheck/github/operations/SearchOp.scala b/src/main/scala/codecheck/github/operations/SearchOp.scala
new file mode 100644
index 0000000..9c81930
--- /dev/null
+++ b/src/main/scala/codecheck/github/operations/SearchOp.scala
@@ -0,0 +1,43 @@
+package codecheck.github.operations
+
+import scala.concurrent.Future
+import scala.concurrent.ExecutionContext.Implicits.global
+
+import codecheck.github.api.GitHubAPI
+import codecheck.github.models.SearchInput
+import codecheck.github.models.SearchRepositoryResult
+import codecheck.github.models.SearchCodeResult
+import codecheck.github.models.SearchIssueResult
+import codecheck.github.models.SearchUserResult
+
+trait SearchOp {
+ self: GitHubAPI =>
+
+  def searchRepositories(input: SearchInput): Future[SearchRepositoryResult] = {
+    val path = s"/search/repositories${input.query}"
+    exec("GET", path ).map { res =>
+      SearchRepositoryResult(res.body)
+   }
+  }
+
+  def searchCode(input: SearchInput): Future[SearchCodeResult] = {
+    val path = s"/search/code${input.query}"
+    exec("GET", path ).map { res =>
+      SearchCodeResult(res.body)
+    }
+  }
+
+  def searchIssues(input: SearchInput): Future[SearchIssueResult] = {
+    val path = s"/search/issues${input.query}"
+    exec("GET", path ).map { res =>
+      SearchIssueResult(res.body)
+    }
+  }
+
+  def searchUser(input: SearchInput): Future[SearchUserResult] = {
+    val path = s"/search/users${input.query}"
+    exec("GET", path ).map { res =>
+      SearchUserResult(res.body)
+    }
+  }
+}
diff --git a/src/test/scala/SearchOpSpec.scala b/src/test/scala/SearchOpSpec.scala
new file mode 100644
index 0000000..3ce9538
--- /dev/null
+++ b/src/test/scala/SearchOpSpec.scala
@@ -0,0 +1,93 @@
+import org.scalatest.path.FunSpec
+import scala.concurrent.Await
+import scala.concurrent.ExecutionContext.Implicits.global
+import codecheck.github.models.SortDirection
+import codecheck.github.models.SearchRepositoryInput
+import codecheck.github.models.SearchCodeInput
+import codecheck.github.models.SearchIssueInput
+import codecheck.github.models.SearchUserInput
+import codecheck.github.models.SearchRepositorySort
+import codecheck.github.models.SearchCodeSort
+import codecheck.github.models.SearchIssueSort
+import codecheck.github.models.SearchUserSort
+import codecheck.github.models.SearchRepositoryResult
+import codecheck.github.models.SearchCodeResult
+import codecheck.github.exceptions.GitHubAPIException
+
+class SearchOpSpec extends FunSpec
+  with Constants
+{
+
+  describe("searchRepositories") {
+    it("with valid SearchInput should succeed") {
+      val q = "tetris language:assembly".trim.replaceAll(" ","+")
+      val input = SearchRepositoryInput(q,sort=Some(SearchRepositorySort.stars),order=SortDirection.desc)
+      val res = Await.result(api.searchRepositories(input), TIMEOUT)
+      assert(res.total_count >= 1)
+      assert(res.items(0).id >= 1 )
+      assert(res.items(0).name.length >= 1)
+      assert(res.items(0).full_name.length >= 1)
+      assert(res.items(0).description.isDefined)
+      assert(res.items(0).open_issues_count >= 0)
+      assert(res.items(0).language == "Assembly")
+      assert(res.items(0).stargazers_count > res.items(1).stargazers_count)
+    }
+    it("with valid changed query(q) SearchInput should succeed") {
+      val q = "jquery in:name,description".trim.replaceAll(" ","+")
+      val input = SearchRepositoryInput(q,sort=Some(SearchRepositorySort.stars),order=SortDirection.desc)
+      val res = Await.result(api.searchRepositories(input), TIMEOUT)
+      assert(res.total_count >= 1)
+      assert(res.items(0).id >= 1 )
+      assert(res.items(0).name.length >= 1)
+      assert(res.items(0).full_name.length >= 1)
+      assert(res.items(0).description.isDefined)
+      assert(res.items(0).open_issues_count >= 0)
+    }
+  }
+  describe("searchCode") {
+    it("with valid SearchInput q,no SortOrder should succeed") {
+      val q = "addClass in:file language:js repo:jquery/jquery".trim.replaceAll(" ","+")
+      val input = SearchCodeInput(q,sort=None,order=SortDirection.desc)
+      val res = Await.result(api.searchCode(input), TIMEOUT)
+      assert(res.total_count >= 1)
+      assert(res.items(0).repository.id >= 1 )
+      assert(res.items(0).sha.length >= 40)
+      assert(res.items(0).score >= 0d)
+      assert(res.items(0).repository.full_name == "jquery/jquery")
+    }
+    it("with valid SearchInput it should succeed") {
+      val q = "function size:10000 language:python".trim.replaceAll(" ","+")
+      val input = SearchCodeInput(q,sort=Some(SearchCodeSort.indexed),order=SortDirection.asc)
+      val res = Await.result(api.searchCode(input), TIMEOUT)
+      assert(res.total_count >= 1)
+      assert(res.items(0).repository.id >= 1 )
+      assert(res.items(0).path.endsWith(".py"))
+      assert(res.items(0).sha.length >= 40)
+      assert(res.items(0).score >= 0d)
+      assert(res.items(0).repository.`private` == false)
+    }
+  }
+  describe("searchIssues") {
+    it("with valid SearchInput should succeed") {
+      val q = "windows label:bug language:python state:open".trim.replaceAll(" ","+")
+      val input = SearchIssueInput(q,sort=Some(SearchIssueSort.created),order=SortDirection.desc)
+      val res = Await.result(api.searchIssues(input), TIMEOUT)
+      assert(res.total_count >= 1)
+      assert(res.items(0).labels(0).name == "bug" )
+      assert(res.items(0).state == "open")
+      assert(((res.items(0).created_at).compareTo(res.items(1).created_at)) > 0)
+    }
+  }
+  describe("searchUser") {
+    it("with valid SearchInput should succeed") {
+      val q = "tom repos:>42 followers:>1000"
+        .trim.replaceAll(" ","+")
+        .replaceAll(">","%3E")
+      val input = SearchUserInput(q,sort=None,order=SortDirection.desc)
+      val res = Await.result(api.searchUser(input), TIMEOUT)
+      assert(res.total_count >= 0)
+      assert(res.items(0).login.length >= 0)
+      assert(res.items(0).id >= 0)
+    }
+  }
+}