{"action":"created","comment":{"url":"https://api.github.com/repos/sonatype/sisu-goodies/pulls/comments/26381125","id":26381125,"diff_hunk":"@@ -0,0 +1,329 @@\n+/*\n+ * Copyright (c) 2007-2014 Sonatype, Inc. All rights reserved.\n+ *\n+ * This program is licensed to you under the Apache License Version 2.0,\n+ * and you may not use this file except in compliance with the Apache License Version 2.0.\n+ * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.\n+ *\n+ * Unless required by applicable law or agreed to in writing,\n+ * software distributed under the Apache License Version 2.0 is distributed on an\n+ * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.\n+ */\n+package org.sonatype.sisu.litmus.testsupport.ldap;\n+\n+import java.io.File;\n+import java.io.IOException;\n+import java.net.ServerSocket;\n+import java.net.URL;\n+import java.util.Arrays;\n+import java.util.Collections;\n+import java.util.HashMap;\n+import java.util.Map;\n+\n+import com.google.common.annotations.VisibleForTesting;\n+import net.sf.ehcache.CacheManager;\n+import net.sf.ehcache.config.Configuration;\n+import net.sf.ehcache.config.ConfigurationFactory;\n+import org.apache.commons.io.FileUtils;\n+import org.apache.directory.api.ldap.model.constants.AuthenticationLevel;\n+import org.apache.directory.api.ldap.model.constants.SchemaConstants;\n+import org.apache.directory.api.ldap.model.constants.SupportedSaslMechanisms;\n+import org.apache.directory.api.ldap.model.schema.SchemaManager;\n+import org.apache.directory.api.ldap.schemamanager.impl.DefaultSchemaManager;\n+import org.apache.directory.server.constants.ServerDNConstants;\n+import org.apache.directory.server.core.DefaultDirectoryService;\n+import org.apache.directory.server.core.api.CacheService;\n+import org.apache.directory.server.core.api.InstanceLayout;\n+import org.apache.directory.server.core.api.InterceptorEnum;\n+import org.apache.directory.server.core.api.partition.Partition;\n+import org.apache.directory.server.core.api.schema.SchemaPartition;\n+import org.apache.directory.server.core.authn.AnonymousAuthenticator;\n+import org.apache.directory.server.core.authn.AuthenticationInterceptor;\n+import org.apache.directory.server.core.authn.Authenticator;\n+import org.apache.directory.server.core.authn.SimpleAuthenticator;\n+import org.apache.directory.server.core.authn.StrongAuthenticator;\n+import org.apache.directory.server.core.factory.AvlPartitionFactory;\n+import org.apache.directory.server.core.factory.PartitionFactory;\n+import org.apache.directory.server.core.partition.ldif.LdifPartition;\n+import org.apache.directory.server.ldap.handlers.sasl.MechanismHandler;\n+import org.apache.directory.server.ldap.handlers.sasl.cramMD5.CramMd5MechanismHandler;\n+import org.apache.directory.server.ldap.handlers.sasl.digestMD5.DigestMd5MechanismHandler;\n+import org.apache.directory.server.protocol.shared.store.LdifFileLoader;\n+import org.apache.directory.server.protocol.shared.transport.TcpTransport;\n+import org.apache.directory.server.protocol.shared.transport.Transport;\n+import org.slf4j.Logger;\n+import org.slf4j.LoggerFactory;\n+\n+/**\n+ * Embedded LDAP server meant to facilitate unit testing of LDAP integration. For convenience, use the\n+ * LdapServerRule subclass in tests.\n+ *\n+ * @since 1.13\n+ */\n+public class LdapServer\n+{\n+  private static final Logger log = LoggerFactory.getLogger(LdapServer.class);\n+\n+  private static final String LOCALHOST = \"localhost\";\n+\n+  private File workingDirectory;\n+\n+  private DefaultDirectoryService directoryService;\n+\n+  private org.apache.directory.server.ldap.LdapServer ldapServer;\n+\n+  private int port;\n+\n+  private AuthenticationLevel authLevel = AuthenticationLevel.NONE;\n+\n+  private Map<String, MechanismHandler> saslHandlers = new HashMap<String, MechanismHandler>();\n+\n+  private String searchBaseDn = \"ou=system\";\n+\n+  private File ldapsKeystore;\n+\n+  private String ldapsKeystorePassword;\n+\n+  private boolean running = false;\n+\n+  public LdapServer(File workingDirectory) {\n+    log.debug(\"Creating LdapServer with workingDirectory={}\",\n+        workingDirectory == null ? null : workingDirectory.getAbsolutePath());\n+    this.workingDirectory = workingDirectory;\n+  }\n+\n+  /**\n+   * Creates new LdapServer instance with conventional work directory target/apacheds\n+   */\n+  public LdapServer() {\n+    this(initWorkingDirectory());\n+  }\n+\n+  private static File initWorkingDirectory() {\n+    File workingDirectory = new File(\"target/apacheds\");\n+    try {\n+      FileUtils.deleteDirectory(workingDirectory);\n+    }\n+    catch (IOException e) {\n+      throw new RuntimeException(e);\n+    }\n+    return workingDirectory;\n+  }\n+\n+  public void start() throws Exception {\n+    if (running) {\n+      throw new IllegalStateException(\"The LdapServer is already running\");\n+    }\n+\n+    long start = System.currentTimeMillis();\n+\n+    if (port <= 0) {\n+      port = getRandomPort();\n+    }\n+\n+    // an example that shows how to create and configure embedded apacheds instance\n+    // http://svn.apache.org/repos/asf/directory/apacheds/trunk/core-annotations/src/main/java/org/apache/directory/server/core/factory/DefaultDirectoryServiceFactory.java\n+\n+    directoryService = new DefaultDirectoryService();\n+\n+    // support multiple embedded ldap servers by assigning each one a distinct cache\n+    URL configURL = getClass().getClassLoader().getResource(\"directory-cacheservice.xml\");\n+    Configuration config = ConfigurationFactory.parseConfiguration(configURL);\n+    config.setName(config.getName() + '_' + System.identityHashCode(this));\n+    directoryService.setCacheService(new CacheService(new CacheManager(config)));\n+\n+    directoryService.setInstanceLayout(new InstanceLayout(workingDirectory));\n+\n+    SchemaManager schemaManager = new DefaultSchemaManager();\n+    directoryService.setSchemaManager(schemaManager);\n+\n+    schemaManager.enable(\"nis\"); // required by group mapping tests\n+\n+    initPartitions(directoryService);\n+\n+    ldapServer = new org.apache.directory.server.ldap.LdapServer();\n+\n+    Transport transport = new TcpTransport(LOCALHOST, port);\n+    transport.setEnableSSL(ldapsKeystore != null);\n+    ldapServer.setTransports(transport);\n+    if (ldapsKeystore != null) {\n+      ldapServer.setKeystoreFile(ldapsKeystore.getCanonicalPath());\n+    }\n+    if (ldapsKeystorePassword != null) {\n+      ldapServer.setCertificatePassword(ldapsKeystorePassword);\n+    }\n+\n+    ldapServer.setDirectoryService(directoryService);\n+\n+    // allowed authentication mechanisms\n+    Authenticator[] authenticators;\n+    switch (authLevel) {\n+      case SIMPLE:\n+        authenticators = new Authenticator[] { new SimpleAuthenticator() };\n+        break;\n+      case STRONG:\n+        authenticators = new Authenticator[] { new StrongAuthenticator() };\n+        ldapServer.setSaslMechanismHandlers(saslHandlers);\n+        ldapServer.setSaslHost(LOCALHOST);\n+        ldapServer.setSaslRealms(Arrays.asList(getSaslRealm()));\n+        ldapServer.setSearchBaseDn(searchBaseDn);\n+        break;\n+      case NONE:\n+      default:\n+        directoryService.setAllowAnonymousAccess(true);\n+        authenticators = new Authenticator[] { new AnonymousAuthenticator(), new SimpleAuthenticator() };\n+        break;\n+    }\n+    AuthenticationInterceptor auth = (AuthenticationInterceptor) directoryService\n+        .getInterceptor(InterceptorEnum.AUTHENTICATION_INTERCEPTOR.getName());\n+    auth.setAuthenticators(authenticators);\n+\n+    directoryService.startup();\n+    ldapServer.start();\n+\n+    running = true;\n+\n+    log.debug(\"Started LdapServer in {} ms\", System.currentTimeMillis() - start);\n+  }\n+\n+  public void loadData(String ldifResourceName) throws IOException {\n+    File ldif = new File(workingDirectory, \"data\" + ldifResourceName);\n+    FileUtils.copyURLToFile(LdapServer.class.getResource(ldifResourceName), ldif);\n+    loadData(ldif);\n+  }\n+\n+  public void loadData(File ldif) {\n+    new LdifFileLoader(directoryService.getAdminSession(), ldif.getAbsolutePath()).execute();\n+  }\n+\n+  private static void initPartitions(DefaultDirectoryService directoryService) throws Exception {\n+    LdifPartition ldifPartition = new LdifPartition(directoryService.getSchemaManager(),\n+        directoryService.getDnFactory());\n+    ldifPartition.setPartitionPath(new File(directoryService.getInstanceLayout().getPartitionsDirectory(), \"schema\")\n+        .toURI());\n+    SchemaPartition schemaPartition = new SchemaPartition(directoryService.getSchemaManager());\n+    schemaPartition.setWrappedPartition(ldifPartition);\n+    directoryService.setSchemaPartition(schemaPartition);\n+    PartitionFactory partitionFactory = new AvlPartitionFactory();\n+\n+    Partition systemPartition = partitionFactory.createPartition(directoryService.getSchemaManager(), directoryService\n+        .getDnFactory(), \"system\", ServerDNConstants.SYSTEM_DN, 500, new File(directoryService.getInstanceLayout()\n+        .getPartitionsDirectory(), \"system\"));\n+    systemPartition.setSchemaManager(directoryService.getSchemaManager());\n+    partitionFactory.addIndex(systemPartition, SchemaConstants.OBJECT_CLASS_AT, 100);\n+    directoryService.setSystemPartition(systemPartition);\n+\n+    Partition sonatypePartition = partitionFactory.createPartition(directoryService.getSchemaManager(),\n+        directoryService.getDnFactory(), \"sonatype\", \"o=sonatype\", 500, new File(directoryService.getInstanceLayout()\n+            .getPartitionsDirectory(), \"sonatype\"));\n+    sonatypePartition.setSchemaManager(directoryService.getSchemaManager());\n+    partitionFactory.addIndex(sonatypePartition, SchemaConstants.OBJECT_CLASS_AT, 100);\n+    directoryService.addPartition(sonatypePartition);\n+\n+    Partition groupsPartition = partitionFactory.createPartition(directoryService.getSchemaManager(), directoryService\n+        .getDnFactory(), \"groups\", \"ou=groups,dc=company,dc=com\", 500, new File(directoryService.getInstanceLayout()\n+        .getPartitionsDirectory(), \"groups\"));\n+    groupsPartition.setSchemaManager(directoryService.getSchemaManager());\n+    partitionFactory.addIndex(groupsPartition, SchemaConstants.OBJECT_CLASS_AT, 100);\n+    directoryService.addPartition(groupsPartition);\n+\n+    Partition usersPartition = partitionFactory.createPartition(directoryService.getSchemaManager(), directoryService\n+        .getDnFactory(), \"users\", \"ou=users,dc=company,dc=com\", 500, new File(directoryService.getInstanceLayout()\n+        .getPartitionsDirectory(), \"users\"));\n+    usersPartition.setSchemaManager(directoryService.getSchemaManager());\n+    partitionFactory.addIndex(usersPartition, SchemaConstants.OBJECT_CLASS_AT, 100);\n+    directoryService.addPartition(usersPartition);\n+\n+    Partition acmeBrickPartition = partitionFactory.createPartition(directoryService.getSchemaManager(),\n+        directoryService.getDnFactory(), \"acme_brick\", \"dc=acme brick,dc=com\", 500, new File(directoryService\n+            .getInstanceLayout().getPartitionsDirectory(), \"acme_brick\"));\n+    acmeBrickPartition.setSchemaManager(directoryService.getSchemaManager());\n+    partitionFactory.addIndex(acmeBrickPartition, SchemaConstants.OBJECT_CLASS_AT, 100);\n+    directoryService.addPartition(acmeBrickPartition);\n+  }\n+\n+  private static int getRandomPort() throws IOException {","path":"testsupport/src/main/java/org/sonatype/sisu/litmus/testsupport/ldap/LdapServer.java","position":null,"original_position":246,"commit_id":"9ae4fdcd04347ba9af4c522afbada56b6b36d8f1","original_commit_id":"765fcd5b74a660bf65077fb9da611b0ae3b7a916","user":{"login":"mcculls","id":145851,"avatar_url":"https://avatars.githubusercontent.com/u/145851?v=3","gravatar_id":"","url":"https://api.github.com/users/mcculls","html_url":"https://github.com/mcculls","followers_url":"https://api.github.com/users/mcculls/followers","following_url":"https://api.github.com/users/mcculls/following{/other_user}","gists_url":"https://api.github.com/users/mcculls/gists{/gist_id}","starred_url":"https://api.github.com/users/mcculls/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mcculls/subscriptions","organizations_url":"https://api.github.com/users/mcculls/orgs","repos_url":"https://api.github.com/users/mcculls/repos","events_url":"https://api.github.com/users/mcculls/events{/privacy}","received_events_url":"https://api.github.com/users/mcculls/received_events","type":"User","site_admin":false},"body":"9ae4fdc","created_at":"2015-03-13T12:20:09Z","updated_at":"2015-03-13T12:20:09Z","html_url":"https://github.com/sonatype/sisu-goodies/pull/35#discussion_r26381125","pull_request_url":"https://api.github.com/repos/sonatype/sisu-goodies/pulls/35","_links":{"self":{"href":"https://api.github.com/repos/sonatype/sisu-goodies/pulls/comments/26381125"},"html":{"href":"https://github.com/sonatype/sisu-goodies/pull/35#discussion_r26381125"},"pull_request":{"href":"https://api.github.com/repos/sonatype/sisu-goodies/pulls/35"}}},"pull_request":{"url":"https://api.github.com/repos/sonatype/sisu-goodies/pulls/35","id":31095107,"html_url":"https://github.com/sonatype/sisu-goodies/pull/35","diff_url":"https://github.com/sonatype/sisu-goodies/pull/35.diff","patch_url":"https://github.com/sonatype/sisu-goodies/pull/35.patch","issue_url":"https://api.github.com/repos/sonatype/sisu-goodies/issues/35","number":35,"state":"open","locked":false,"title":"Optional LDAP testsupport","user":{"login":"mcculls","id":145851,"avatar_url":"https://avatars.githubusercontent.com/u/145851?v=3","gravatar_id":"","url":"https://api.github.com/users/mcculls","html_url":"https://github.com/mcculls","followers_url":"https://api.github.com/users/mcculls/followers","following_url":"https://api.github.com/users/mcculls/following{/other_user}","gists_url":"https://api.github.com/users/mcculls/gists{/gist_id}","starred_url":"https://api.github.com/users/mcculls/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mcculls/subscriptions","organizations_url":"https://api.github.com/users/mcculls/orgs","repos_url":"https://api.github.com/users/mcculls/repos","events_url":"https://api.github.com/users/mcculls/events{/privacy}","received_events_url":"https://api.github.com/users/mcculls/received_events","type":"User","site_admin":false},"body":"Based on the modern LDAP test code from clm-land","created_at":"2015-03-13T02:15:44Z","updated_at":"2015-03-13T12:20:09Z","closed_at":null,"merged_at":null,"merge_commit_sha":"cfc0ee39ce1506cf48c5d328f832847a2510387a","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/sonatype/sisu-goodies/pulls/35/commits","review_comments_url":"https://api.github.com/repos/sonatype/sisu-goodies/pulls/35/comments","review_comment_url":"https://api.github.com/repos/sonatype/sisu-goodies/pulls/comments{/number}","comments_url":"https://api.github.com/repos/sonatype/sisu-goodies/issues/35/comments","statuses_url":"https://api.github.com/repos/sonatype/sisu-goodies/statuses/9ae4fdcd04347ba9af4c522afbada56b6b36d8f1","head":{"label":"sonatype:optional-ldap-testsupport","ref":"optional-ldap-testsupport","sha":"9ae4fdcd04347ba9af4c522afbada56b6b36d8f1","user":{"login":"sonatype","id":44938,"avatar_url":"https://avatars.githubusercontent.com/u/44938?v=3","gravatar_id":"","url":"https://api.github.com/users/sonatype","html_url":"https://github.com/sonatype","followers_url":"https://api.github.com/users/sonatype/followers","following_url":"https://api.github.com/users/sonatype/following{/other_user}","gists_url":"https://api.github.com/users/sonatype/gists{/gist_id}","starred_url":"https://api.github.com/users/sonatype/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sonatype/subscriptions","organizations_url":"https://api.github.com/users/sonatype/orgs","repos_url":"https://api.github.com/users/sonatype/repos","events_url":"https://api.github.com/users/sonatype/events{/privacy}","received_events_url":"https://api.github.com/users/sonatype/received_events","type":"Organization","site_admin":false},"repo":{"id":2698192,"name":"sisu-goodies","full_name":"sonatype/sisu-goodies","owner":{"login":"sonatype","id":44938,"avatar_url":"https://avatars.githubusercontent.com/u/44938?v=3","gravatar_id":"","url":"https://api.github.com/users/sonatype","html_url":"https://github.com/sonatype","followers_url":"https://api.github.com/users/sonatype/followers","following_url":"https://api.github.com/users/sonatype/following{/other_user}","gists_url":"https://api.github.com/users/sonatype/gists{/gist_id}","starred_url":"https://api.github.com/users/sonatype/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sonatype/subscriptions","organizations_url":"https://api.github.com/users/sonatype/orgs","repos_url":"https://api.github.com/users/sonatype/repos","events_url":"https://api.github.com/users/sonatype/events{/privacy}","received_events_url":"https://api.github.com/users/sonatype/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/sonatype/sisu-goodies","description":"","fork":false,"url":"https://api.github.com/repos/sonatype/sisu-goodies","forks_url":"https://api.github.com/repos/sonatype/sisu-goodies/forks","keys_url":"https://api.github.com/repos/sonatype/sisu-goodies/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sonatype/sisu-goodies/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sonatype/sisu-goodies/teams","hooks_url":"https://api.github.com/repos/sonatype/sisu-goodies/hooks","issue_events_url":"https://api.github.com/repos/sonatype/sisu-goodies/issues/events{/number}","events_url":"https://api.github.com/repos/sonatype/sisu-goodies/events","assignees_url":"https://api.github.com/repos/sonatype/sisu-goodies/assignees{/user}","branches_url":"https://api.github.com/repos/sonatype/sisu-goodies/branches{/branch}","tags_url":"https://api.github.com/repos/sonatype/sisu-goodies/tags","blobs_url":"https://api.github.com/repos/sonatype/sisu-goodies/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sonatype/sisu-goodies/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sonatype/sisu-goodies/git/refs{/sha}","trees_url":"https://api.github.com/repos/sonatype/sisu-goodies/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sonatype/sisu-goodies/statuses/{sha}","languages_url":"https://api.github.com/repos/sonatype/sisu-goodies/languages","stargazers_url":"https://api.github.com/repos/sonatype/sisu-goodies/stargazers","contributors_url":"https://api.github.com/repos/sonatype/sisu-goodies/contributors","subscribers_url":"https://api.github.com/repos/sonatype/sisu-goodies/subscribers","subscription_url":"https://api.github.com/repos/sonatype/sisu-goodies/subscription","commits_url":"https://api.github.com/repos/sonatype/sisu-goodies/commits{/sha}","git_commits_url":"https://api.github.com/repos/sonatype/sisu-goodies/git/commits{/sha}","comments_url":"https://api.github.com/repos/sonatype/sisu-goodies/comments{/number}","issue_comment_url":"https://api.github.com/repos/sonatype/sisu-goodies/issues/comments{/number}","contents_url":"https://api.github.com/repos/sonatype/sisu-goodies/contents/{+path}","compare_url":"https://api.github.com/repos/sonatype/sisu-goodies/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sonatype/sisu-goodies/merges","archive_url":"https://api.github.com/repos/sonatype/sisu-goodies/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sonatype/sisu-goodies/downloads","issues_url":"https://api.github.com/repos/sonatype/sisu-goodies/issues{/number}","pulls_url":"https://api.github.com/repos/sonatype/sisu-goodies/pulls{/number}","milestones_url":"https://api.github.com/repos/sonatype/sisu-goodies/milestones{/number}","notifications_url":"https://api.github.com/repos/sonatype/sisu-goodies/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sonatype/sisu-goodies/labels{/name}","releases_url":"https://api.github.com/repos/sonatype/sisu-goodies/releases{/id}","created_at":"2011-11-02T21:23:34Z","updated_at":"2015-02-26T00:52:50Z","pushed_at":"2015-03-13T12:19:58Z","git_url":"git://github.com/sonatype/sisu-goodies.git","ssh_url":"git@github.com:sonatype/sisu-goodies.git","clone_url":"https://github.com/sonatype/sisu-goodies.git","svn_url":"https://github.com/sonatype/sisu-goodies","homepage":"","size":1919,"stargazers_count":3,"watchers_count":3,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":1,"forks":1,"open_issues":1,"watchers":3,"default_branch":"master"}},"base":{"label":"sonatype:master","ref":"master","sha":"29ba29277b8fdeeac5bdb8eab18eab34e9c36aa8","user":{"login":"sonatype","id":44938,"avatar_url":"https://avatars.githubusercontent.com/u/44938?v=3","gravatar_id":"","url":"https://api.github.com/users/sonatype","html_url":"https://github.com/sonatype","followers_url":"https://api.github.com/users/sonatype/followers","following_url":"https://api.github.com/users/sonatype/following{/other_user}","gists_url":"https://api.github.com/users/sonatype/gists{/gist_id}","starred_url":"https://api.github.com/users/sonatype/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sonatype/subscriptions","organizations_url":"https://api.github.com/users/sonatype/orgs","repos_url":"https://api.github.com/users/sonatype/repos","events_url":"https://api.github.com/users/sonatype/events{/privacy}","received_events_url":"https://api.github.com/users/sonatype/received_events","type":"Organization","site_admin":false},"repo":{"id":2698192,"name":"sisu-goodies","full_name":"sonatype/sisu-goodies","owner":{"login":"sonatype","id":44938,"avatar_url":"https://avatars.githubusercontent.com/u/44938?v=3","gravatar_id":"","url":"https://api.github.com/users/sonatype","html_url":"https://github.com/sonatype","followers_url":"https://api.github.com/users/sonatype/followers","following_url":"https://api.github.com/users/sonatype/following{/other_user}","gists_url":"https://api.github.com/users/sonatype/gists{/gist_id}","starred_url":"https://api.github.com/users/sonatype/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sonatype/subscriptions","organizations_url":"https://api.github.com/users/sonatype/orgs","repos_url":"https://api.github.com/users/sonatype/repos","events_url":"https://api.github.com/users/sonatype/events{/privacy}","received_events_url":"https://api.github.com/users/sonatype/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/sonatype/sisu-goodies","description":"","fork":false,"url":"https://api.github.com/repos/sonatype/sisu-goodies","forks_url":"https://api.github.com/repos/sonatype/sisu-goodies/forks","keys_url":"https://api.github.com/repos/sonatype/sisu-goodies/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sonatype/sisu-goodies/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sonatype/sisu-goodies/teams","hooks_url":"https://api.github.com/repos/sonatype/sisu-goodies/hooks","issue_events_url":"https://api.github.com/repos/sonatype/sisu-goodies/issues/events{/number}","events_url":"https://api.github.com/repos/sonatype/sisu-goodies/events","assignees_url":"https://api.github.com/repos/sonatype/sisu-goodies/assignees{/user}","branches_url":"https://api.github.com/repos/sonatype/sisu-goodies/branches{/branch}","tags_url":"https://api.github.com/repos/sonatype/sisu-goodies/tags","blobs_url":"https://api.github.com/repos/sonatype/sisu-goodies/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sonatype/sisu-goodies/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sonatype/sisu-goodies/git/refs{/sha}","trees_url":"https://api.github.com/repos/sonatype/sisu-goodies/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sonatype/sisu-goodies/statuses/{sha}","languages_url":"https://api.github.com/repos/sonatype/sisu-goodies/languages","stargazers_url":"https://api.github.com/repos/sonatype/sisu-goodies/stargazers","contributors_url":"https://api.github.com/repos/sonatype/sisu-goodies/contributors","subscribers_url":"https://api.github.com/repos/sonatype/sisu-goodies/subscribers","subscription_url":"https://api.github.com/repos/sonatype/sisu-goodies/subscription","commits_url":"https://api.github.com/repos/sonatype/sisu-goodies/commits{/sha}","git_commits_url":"https://api.github.com/repos/sonatype/sisu-goodies/git/commits{/sha}","comments_url":"https://api.github.com/repos/sonatype/sisu-goodies/comments{/number}","issue_comment_url":"https://api.github.com/repos/sonatype/sisu-goodies/issues/comments{/number}","contents_url":"https://api.github.com/repos/sonatype/sisu-goodies/contents/{+path}","compare_url":"https://api.github.com/repos/sonatype/sisu-goodies/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sonatype/sisu-goodies/merges","archive_url":"https://api.github.com/repos/sonatype/sisu-goodies/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sonatype/sisu-goodies/downloads","issues_url":"https://api.github.com/repos/sonatype/sisu-goodies/issues{/number}","pulls_url":"https://api.github.com/repos/sonatype/sisu-goodies/pulls{/number}","milestones_url":"https://api.github.com/repos/sonatype/sisu-goodies/milestones{/number}","notifications_url":"https://api.github.com/repos/sonatype/sisu-goodies/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sonatype/sisu-goodies/labels{/name}","releases_url":"https://api.github.com/repos/sonatype/sisu-goodies/releases{/id}","created_at":"2011-11-02T21:23:34Z","updated_at":"2015-02-26T00:52:50Z","pushed_at":"2015-03-13T12:19:58Z","git_url":"git://github.com/sonatype/sisu-goodies.git","ssh_url":"git@github.com:sonatype/sisu-goodies.git","clone_url":"https://github.com/sonatype/sisu-goodies.git","svn_url":"https://github.com/sonatype/sisu-goodies","homepage":"","size":1919,"stargazers_count":3,"watchers_count":3,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":1,"forks":1,"open_issues":1,"watchers":3,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/sonatype/sisu-goodies/pulls/35"},"html":{"href":"https://github.com/sonatype/sisu-goodies/pull/35"},"issue":{"href":"https://api.github.com/repos/sonatype/sisu-goodies/issues/35"},"comments":{"href":"https://api.github.com/repos/sonatype/sisu-goodies/issues/35/comments"},"review_comments":{"href":"https://api.github.com/repos/sonatype/sisu-goodies/pulls/35/comments"},"review_comment":{"href":"https://api.github.com/repos/sonatype/sisu-goodies/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/sonatype/sisu-goodies/pulls/35/commits"},"statuses":{"href":"https://api.github.com/repos/sonatype/sisu-goodies/statuses/9ae4fdcd04347ba9af4c522afbada56b6b36d8f1"}}}}