{"action":"created","comment":{"url":"https://api.github.com/repos/camelot-framework/camelot/pulls/comments/40464636","id":40464636,"diff_hunk":"@@ -0,0 +1,458 @@\n+package ru.yandex.qatools.camelot.util;\n+\n+import org.apache.commons.lang3.ArrayUtils;\n+import org.slf4j.Logger;\n+import org.slf4j.LoggerFactory;\n+\n+import java.lang.annotation.Annotation;\n+import java.lang.reflect.*;\n+import java.util.*;\n+\n+import static java.util.Arrays.asList;\n+import static org.apache.commons.lang3.ClassUtils.getAllInterfaces;\n+\n+/**\n+ * Util class allowing to scan all the classes inside the specified package and other class operations\n+ * User: isadykov\n+ * Date: 16.03.12\n+ * Time: 15:55\n+ */\n+public class ReflectUtil {\n+\n+    private static final Logger logger = LoggerFactory.getLogger(ReflectUtil.class);\n+\n+    public static interface ExceptionHandler {\n+        Object handleException(Throwable e) throws Throwable;\n+    }\n+\n+    /**\n+     * Create a proxy object implementing some interface from a specified class loader\n+     */\n+    @SuppressWarnings(\"unchecked\")\n+    public static <C, I extends C> I classLoaderProxy(ClassLoader cl, C object, Class<I> classInterface)\n+            throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {\n+        return (I) Proxy.newProxyInstance(classInterface.getClassLoader(), new Class[]{classInterface}, new ThroughClassLoaderProxyHandler(object, cl));\n+    }\n+\n+\n+    /**\n+     * An invocation handler that passes on any calls made to it directly to its delegate.\n+     * This is useful to handle identical classes loaded in different classloaders - the\n+     * VM treats them as different classes, but they have identical signatures.\n+     * <p/>\n+     * Note this is using class.getMethod, which will only work on public methods.\n+     * Note this is using the arguments that are of primitive types/ types from java.lang / classes implementing one\n+     * interface exactly\n+     */\n+    private static class ThroughClassLoaderProxyHandler implements InvocationHandler {\n+        private final Object delegate;\n+        private final ClassLoader guestClassLoader;\n+        private final ClassLoader hostClassLoader;\n+        private final ExceptionHandler exceptionHandler;\n+\n+        public ThroughClassLoaderProxyHandler(Object delegate, ClassLoader classLoader, ExceptionHandler handler) {\n+            this.delegate = delegate;\n+            this.guestClassLoader = classLoader;\n+            this.hostClassLoader = getClass().getClassLoader();\n+            this.exceptionHandler = handler;\n+        }\n+\n+        public ThroughClassLoaderProxyHandler(Object delegate, ClassLoader classLoader) {\n+            this(delegate, classLoader, null);\n+        }\n+\n+        public Object invoke(Object proxy, Method method, Object[] args)\n+                throws Throwable {\n+            try {\n+                Method delegateMethod = delegate.getClass().getMethod(method.getName(),\n+                        wrapTypesForClassLoader(guestClassLoader, method.getParameterTypes()));\n+                return wrapObjectForClassLoader(\n+                        hostClassLoader,\n+                        guestClassLoader,\n+                        delegateMethod.invoke(delegate,\n+                                wrapArgsForClassLoader(guestClassLoader, hostClassLoader, delegateMethod, args)\n+                        ),\n+                        null\n+                );\n+            } catch (Exception e) {\n+                logger.error(\"Failed to invoke method \" + method.getName() + \" on proxy \" + proxy, e);\n+                return throwRootExceptionFromClassLoader(hostClassLoader, e, exceptionHandler);\n+            }\n+        }\n+    }\n+\n+    /**\n+     * Collect all interfaces of a class\n+     */\n+    private static Set<Class> collectAllClassInterfaces(final Class objClazz) {\n+        Set<Class> interfaces = new HashSet<>();\n+        Class clazz = objClazz;\n+        // search through superclasses\n+        while (clazz != null) {\n+            interfaces.addAll(asList(clazz.getInterfaces()));\n+            clazz = clazz.getSuperclass();\n+        }\n+        return interfaces;\n+    }\n+\n+    /**\n+     * Throw an exception which is a root cause of the problem, creating the same instance in the host class loader\n+     */\n+    @SuppressWarnings(\"unchecked\")\n+    private static Object throwRootExceptionFromClassLoader(ClassLoader cl, Exception e, ExceptionHandler handler)\n+            throws Throwable {\n+        Throwable rootE = getRootException(e);\n+        Class<? extends Throwable> eClass = (Class<? extends Throwable>) cl.loadClass(rootE.getClass().getName());\n+        Throwable resultException = e;\n+        try {\n+            resultException = eClass.getConstructor(Throwable.class).newInstance(rootE);\n+        } catch (NoSuchMethodException ignored) {\n+            logger.trace(\"Ignored exception\", ignored);\n+            try {\n+                resultException = (eClass.getConstructor(String.class).newInstance(rootE.getMessage()));\n+            } catch (NoSuchMethodException ignored2) {\n+                logger.trace(\"Ignored exception\", ignored2);\n+                resultException = eClass.newInstance();\n+            }\n+        }\n+        if (handler != null) {\n+            return handler.handleException(resultException);\n+        }\n+        resultException.setStackTrace(rootE.getStackTrace());\n+        throw resultException;\n+    }\n+\n+    /**\n+     * Retrieve the root exception through getCause()\n+     */\n+    private static Throwable getRootException(Exception e) {\n+        Throwable rootE = e;\n+        while (rootE.getCause() != null) {\n+            rootE = rootE.getCause();\n+        }\n+        return rootE;\n+    }\n+\n+    /**\n+     * Load type's class from a specified classloader.\n+     * If a type is basic or from basic \"java\" package return itself.\n+     */\n+    private static Class<?> classLoaderType(ClassLoader cl, Class<?> type) throws ClassNotFoundException {\n+        return isBasicJavaType(type) ? type : cl.loadClass(type.getName());\n+    }\n+\n+    /**\n+     * returns true if a type is a basic java type\n+     */\n+    private static boolean isBasicJavaType(Class<?> type) {\n+        return type.getPackage() == null || type.getPackage().getName().startsWith(\"java\");\n+    }\n+\n+    /**\n+     * Get parameter types list from a class loader.\n+     */\n+    private static Class<?>[] wrapTypesForClassLoader(ClassLoader cl, Class<?>[] types)\n+            throws ClassNotFoundException {\n+        List<Class<?>> res = new ArrayList<>();\n+        if (types != null) {\n+            for (Class<?> type : types) {\n+                Class<?> clazz = classLoaderType(cl, type);\n+                res.add(clazz);\n+            }\n+        }\n+        return res.toArray(new Class<?>[res.size()]);\n+    }\n+\n+    /**\n+     * Wrap args for a class loader (if necessary)\n+     *\n+     * @param hostCL  specifies a host class loader (from which argument is accessible)\n+     * @param method  specifies a method that should be used for wrapping\n+     * @param guestCL specifies a guest class loader (which is supposed to be the actual consumer of the arguments)\n+     */\n+    private static Object[] wrapArgsForClassLoader(ClassLoader hostCL, ClassLoader guestCL, Method method, Object[] args)\n+            throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {\n+        List<Object> wrappedArgs = new ArrayList<>();\n+        if (args != null) {\n+            if (method.getParameterTypes().length != args.length) {\n+                throw new RuntimeException(\"Cannot wrap arguments: method \" + method.getName() + \" is expecting \" +\n+                        method.getParameterTypes().length + \" args, but only \" + args.length + \" provided!\");\n+            }\n+            for (int i = 0; i < method.getParameterTypes().length; ++i) {\n+                wrappedArgs.add(wrapObjectForClassLoader(hostCL, guestCL, args[i], method.getParameterTypes()[i]));\n+            }\n+        }\n+        return wrappedArgs.toArray(new Object[wrappedArgs.size()]);\n+    }\n+\n+    /**\n+     * Wrap object for a class loader (if necessary)\n+     *\n+     * @param hostCL       specifies a host class loader (from which argument is accessible)\n+     * @param guestCL      specifies a guest class loader (which is supposed to be the actual consumer of the arguments)\n+     * @param originalType type that must be used for wrapping\n+     */\n+    private static Object wrapObjectForClassLoader(ClassLoader hostCL, ClassLoader guestCL, Object arg, Class originalType)\n+            throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {\n+        if (arg == null) {\n+            return null;\n+        }\n+        if (arg instanceof Collection) {\n+            Collection newList = instantiateCollection((Class<? extends Collection>) arg.getClass());\n+            for (Object item : (Collection) arg) {\n+                newList.add(wrapObjectForClassLoader(hostCL, guestCL, item, originalType));\n+            }\n+            return newList;\n+        } else if (arg instanceof Enum) {\n+            return EnumUtil.fromString((Class<Enum>) guestCL.loadClass(arg.getClass().getName()), ((Enum) arg).name());\n+        } else if (!isBasicJavaType(arg.getClass())) {\n+            if (originalType != null) {\n+                return classLoaderProxy(hostCL, arg, originalType);\n+            }\n+            // if this is a not a basic type or a type from java base package, we must create proxy for it (if it\n+            // implements exactly one interface)\n+            return classLoaderProxy(hostCL, arg, guestCL.loadClass(getClassSingleInterface(arg.getClass()).getName()));\n+        } else if (arg instanceof Class) {\n+            // this is a class, we must load it from guest CL\n+            return guestCL.loadClass(((Class) arg).getName());\n+        } else {\n+            // this is probably a primitive type or basic class, we can pass it through as it is\n+            return (arg);\n+        }\n+    }\n+\n+    /**\n+     * Instantiate the collection by its class\n+     *\n+     * @param collClass\n+     * @return\n+     */\n+    public static Collection instantiateCollection(Class<? extends Collection> collClass) throws IllegalAccessException, InstantiationException {\n+        if (List.class.isAssignableFrom(collClass)) {\n+            return new ArrayList();\n+        } else if (Set.class.isAssignableFrom(collClass)) {\n+            return new HashSet();\n+        } else if (!collClass.isInterface() && !Modifier.isAbstract(collClass.getModifiers())) {\n+            return collClass.newInstance();\n+        } else {\n+            throw new RuntimeException(\"Cannot instantiate collection of a class: \" + collClass + \": Not supported!\");\n+        }\n+    }\n+\n+\n+    /**\n+     * Returns single interface for a class.\n+     * Throws an exception if a class has more than 1 or has no interfaces\n+     */\n+    private static <T> Class<?> getClassSingleInterface(Class<T> clazz) {\n+        List<Class<?>> interfaces = getNonBasicJavaInterfaces(clazz, false);\n+        if (interfaces.size() != 1) {\n+            throw new IllegalArgumentException(\"Class \" + clazz.getName() + \" must implement exactly one non-basic java interface!\");\n+        }\n+        return interfaces.get(0);\n+    }\n+\n+    /**\n+     * Returns non-basic java interfaces of a class\n+     */\n+    private static List<Class<?>> getNonBasicJavaInterfaces(Class<?> clazz, boolean includeSuperClasses) {\n+        List<Class<?>> result = new ArrayList<>();\n+        final List allInterfaces = (includeSuperClasses) ? getAllInterfaces(clazz) : asList(clazz.getInterfaces());\n+        for (Object iface : allInterfaces) {\n+            if (!isBasicJavaType((Class<?>) iface)) {\n+                result.add((Class<?>) iface);\n+            }\n+        }\n+        return result;\n+    }\n+\n+    /**\n+     * Returns the list of classes for the arguments from the different classloader\n+     */\n+    public static Class<?>[] getArgTypes(Object[] arguments, ClassLoader classLoader) throws ClassNotFoundException {\n+        List<Class<?>> types = new ArrayList<>();\n+        for (Object arg : arguments) {\n+            types.add(classLoader.loadClass(arg.getClass().getName()));\n+        }\n+        return types.toArray(new Class<?>[types.size()]);\n+    }\n+\n+\n+    /**\n+     * Searches for a certain annotation in the class hierarchy\n+     *\n+     * @param annotatedClass\n+     * @param annotationClass\n+     * @param <T>\n+     * @return\n+     */\n+    public static <T extends Annotation> T findAnnotationInClassHierarchy(Class<?> annotatedClass, Class<T> annotationClass) {\n+        T result = null;\n+        while (annotatedClass != null && result == null) {\n+            result = annotatedClass.getAnnotation(annotationClass);\n+            annotatedClass = annotatedClass.getSuperclass();\n+        }\n+        return result;\n+    }\n+\n+    /**\n+     * Searches for all fields within class hierarchy\n+     *\n+     * @return\n+     */\n+    public static Field[] getFieldsInClassHierarchy(Class<?> clazz) {\n+        Field[] fields = {};\n+        while (clazz != null) {\n+            fields = ArrayUtils.addAll(fields, clazz.getDeclaredFields());\n+            clazz = clazz.getSuperclass();\n+        }\n+        return fields;\n+    }\n+\n+    /**\n+     * Searches for the method within class hierarchy\n+     *\n+     * @return\n+     */\n+    public static Method getMethodFromClassHierarchy(Class<?> clazz, String methodName) throws NoSuchMethodException {\n+        while (clazz != null) {\n+            for (Method method : clazz.getDeclaredMethods()) {\n+                if (method.getName().equals(methodName)) {\n+                    return method;\n+                }\n+            }\n+            clazz = clazz.getSuperclass();\n+        }\n+        throw new NoSuchMethodException(methodName);\n+    }\n+\n+    /**\n+     * Searches for all methods within class hierarchy\n+     *\n+     * @return\n+     */\n+    public static Method[] getMethodsInClassHierarchy(Class<?> clazz) {\n+        Method[] methods = {};\n+        while (clazz != null) {\n+            methods = ArrayUtils.addAll(methods, clazz.getDeclaredMethods());\n+            clazz = clazz.getSuperclass();\n+        }\n+        return methods;\n+    }\n+\n+    /**\n+     * Returns the generic arguments from the field\n+     *\n+     * @param field - field to be reflect\n+     * @return Type arguments array\n+     */\n+    public static Type[] getFieldTypeArguments(Field field) {\n+        Type genericFieldType = field.getGenericType();\n+        if (genericFieldType instanceof ParameterizedType) {\n+            ParameterizedType aType = (ParameterizedType) genericFieldType;\n+            return aType.getActualTypeArguments();\n+        }\n+        return new Type[]{};\n+    }\n+\n+    /**\n+     * Invokes any object method (even if it's private)\n+     */\n+    public static <T> Object invokeAnyMethod(Class<?> clazz, T instance, String method, Class<?>[] argTypes,\n+                                             Object... arguments) throws\n+            NoSuchMethodException, InvocationTargetException, IllegalAccessException {\n+        List<Class<?>> types = new ArrayList<>();\n+        if (argTypes == null) {\n+            for (Object arg : arguments) {\n+                types.add(arg.getClass());\n+            }\n+            argTypes = types.toArray(new Class<?>[types.size()]);","path":"camelot-api/src/main/java/ru/yandex/qatools/camelot/util/ReflectUtil.java","position":369,"original_position":369,"commit_id":"60a16cd8c2933063603212890bbbcebdd1d41916","original_commit_id":"60a16cd8c2933063603212890bbbcebdd1d41916","user":{"login":"qatools-ci","id":4466920,"avatar_url":"https://avatars.githubusercontent.com/u/4466920?v=3","gravatar_id":"","url":"https://api.github.com/users/qatools-ci","html_url":"https://github.com/qatools-ci","followers_url":"https://api.github.com/users/qatools-ci/followers","following_url":"https://api.github.com/users/qatools-ci/following{/other_user}","gists_url":"https://api.github.com/users/qatools-ci/gists{/gist_id}","starred_url":"https://api.github.com/users/qatools-ci/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/qatools-ci/subscriptions","organizations_url":"https://api.github.com/users/qatools-ci/orgs","repos_url":"https://api.github.com/users/qatools-ci/repos","events_url":"https://api.github.com/users/qatools-ci/events{/privacy}","received_events_url":"https://api.github.com/users/qatools-ci/received_events","type":"User","site_admin":false},"body":"![MAJOR](https://raw.githubusercontent.com/SonarCommunity/sonar-github/master/images/severity-major.png) Introduce a new variable instead of reusing the parameter \"argTypes\". [![rule](https://raw.githubusercontent.com/SonarCommunity/sonar-github/master/images/rule.png)](http://nemo.sonarqube.org/coding_rules#rule_key=squid%3AS1226)\n","created_at":"2015-09-25T19:01:32Z","updated_at":"2015-09-25T19:01:32Z","html_url":"https://github.com/camelot-framework/camelot/pull/95#discussion_r40464636","pull_request_url":"https://api.github.com/repos/camelot-framework/camelot/pulls/95","_links":{"self":{"href":"https://api.github.com/repos/camelot-framework/camelot/pulls/comments/40464636"},"html":{"href":"https://github.com/camelot-framework/camelot/pull/95#discussion_r40464636"},"pull_request":{"href":"https://api.github.com/repos/camelot-framework/camelot/pulls/95"}}},"pull_request":{"url":"https://api.github.com/repos/camelot-framework/camelot/pulls/95","id":45896002,"html_url":"https://github.com/camelot-framework/camelot/pull/95","diff_url":"https://github.com/camelot-framework/camelot/pull/95.diff","patch_url":"https://github.com/camelot-framework/camelot/pull/95.patch","issue_url":"https://api.github.com/repos/camelot-framework/camelot/issues/95","number":95,"state":"open","locked":false,"title":"Repackage standalone to be able to modify classpath via /lib directory","user":{"login":"smecsia","id":214657,"avatar_url":"https://avatars.githubusercontent.com/u/214657?v=3","gravatar_id":"","url":"https://api.github.com/users/smecsia","html_url":"https://github.com/smecsia","followers_url":"https://api.github.com/users/smecsia/followers","following_url":"https://api.github.com/users/smecsia/following{/other_user}","gists_url":"https://api.github.com/users/smecsia/gists{/gist_id}","starred_url":"https://api.github.com/users/smecsia/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/smecsia/subscriptions","organizations_url":"https://api.github.com/users/smecsia/orgs","repos_url":"https://api.github.com/users/smecsia/repos","events_url":"https://api.github.com/users/smecsia/events{/privacy}","received_events_url":"https://api.github.com/users/smecsia/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-09-24T13:22:44Z","updated_at":"2015-09-25T19:01:32Z","closed_at":null,"merged_at":null,"merge_commit_sha":"679556f8c4b51818108538a94385d216abbaf6b2","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/camelot-framework/camelot/pulls/95/commits","review_comments_url":"https://api.github.com/repos/camelot-framework/camelot/pulls/95/comments","review_comment_url":"https://api.github.com/repos/camelot-framework/camelot/pulls/comments{/number}","comments_url":"https://api.github.com/repos/camelot-framework/camelot/issues/95/comments","statuses_url":"https://api.github.com/repos/camelot-framework/camelot/statuses/60a16cd8c2933063603212890bbbcebdd1d41916","head":{"label":"smecsia:master","ref":"master","sha":"60a16cd8c2933063603212890bbbcebdd1d41916","user":{"login":"smecsia","id":214657,"avatar_url":"https://avatars.githubusercontent.com/u/214657?v=3","gravatar_id":"","url":"https://api.github.com/users/smecsia","html_url":"https://github.com/smecsia","followers_url":"https://api.github.com/users/smecsia/followers","following_url":"https://api.github.com/users/smecsia/following{/other_user}","gists_url":"https://api.github.com/users/smecsia/gists{/gist_id}","starred_url":"https://api.github.com/users/smecsia/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/smecsia/subscriptions","organizations_url":"https://api.github.com/users/smecsia/orgs","repos_url":"https://api.github.com/users/smecsia/repos","events_url":"https://api.github.com/users/smecsia/events{/privacy}","received_events_url":"https://api.github.com/users/smecsia/received_events","type":"User","site_admin":false},"repo":{"id":22915597,"name":"camelot","full_name":"smecsia/camelot","owner":{"login":"smecsia","id":214657,"avatar_url":"https://avatars.githubusercontent.com/u/214657?v=3","gravatar_id":"","url":"https://api.github.com/users/smecsia","html_url":"https://github.com/smecsia","followers_url":"https://api.github.com/users/smecsia/followers","following_url":"https://api.github.com/users/smecsia/following{/other_user}","gists_url":"https://api.github.com/users/smecsia/gists{/gist_id}","starred_url":"https://api.github.com/users/smecsia/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/smecsia/subscriptions","organizations_url":"https://api.github.com/users/smecsia/orgs","repos_url":"https://api.github.com/users/smecsia/repos","events_url":"https://api.github.com/users/smecsia/events{/privacy}","received_events_url":"https://api.github.com/users/smecsia/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/smecsia/camelot","description":"Simplified scalable aggregation and processing framework built upon Apache Camel.","fork":true,"url":"https://api.github.com/repos/smecsia/camelot","forks_url":"https://api.github.com/repos/smecsia/camelot/forks","keys_url":"https://api.github.com/repos/smecsia/camelot/keys{/key_id}","collaborators_url":"https://api.github.com/repos/smecsia/camelot/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/smecsia/camelot/teams","hooks_url":"https://api.github.com/repos/smecsia/camelot/hooks","issue_events_url":"https://api.github.com/repos/smecsia/camelot/issues/events{/number}","events_url":"https://api.github.com/repos/smecsia/camelot/events","assignees_url":"https://api.github.com/repos/smecsia/camelot/assignees{/user}","branches_url":"https://api.github.com/repos/smecsia/camelot/branches{/branch}","tags_url":"https://api.github.com/repos/smecsia/camelot/tags","blobs_url":"https://api.github.com/repos/smecsia/camelot/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/smecsia/camelot/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/smecsia/camelot/git/refs{/sha}","trees_url":"https://api.github.com/repos/smecsia/camelot/git/trees{/sha}","statuses_url":"https://api.github.com/repos/smecsia/camelot/statuses/{sha}","languages_url":"https://api.github.com/repos/smecsia/camelot/languages","stargazers_url":"https://api.github.com/repos/smecsia/camelot/stargazers","contributors_url":"https://api.github.com/repos/smecsia/camelot/contributors","subscribers_url":"https://api.github.com/repos/smecsia/camelot/subscribers","subscription_url":"https://api.github.com/repos/smecsia/camelot/subscription","commits_url":"https://api.github.com/repos/smecsia/camelot/commits{/sha}","git_commits_url":"https://api.github.com/repos/smecsia/camelot/git/commits{/sha}","comments_url":"https://api.github.com/repos/smecsia/camelot/comments{/number}","issue_comment_url":"https://api.github.com/repos/smecsia/camelot/issues/comments{/number}","contents_url":"https://api.github.com/repos/smecsia/camelot/contents/{+path}","compare_url":"https://api.github.com/repos/smecsia/camelot/compare/{base}...{head}","merges_url":"https://api.github.com/repos/smecsia/camelot/merges","archive_url":"https://api.github.com/repos/smecsia/camelot/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/smecsia/camelot/downloads","issues_url":"https://api.github.com/repos/smecsia/camelot/issues{/number}","pulls_url":"https://api.github.com/repos/smecsia/camelot/pulls{/number}","milestones_url":"https://api.github.com/repos/smecsia/camelot/milestones{/number}","notifications_url":"https://api.github.com/repos/smecsia/camelot/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/smecsia/camelot/labels{/name}","releases_url":"https://api.github.com/repos/smecsia/camelot/releases{/id}","created_at":"2014-08-13T12:56:57Z","updated_at":"2015-04-29T13:19:37Z","pushed_at":"2015-09-25T18:53:19Z","git_url":"git://github.com/smecsia/camelot.git","ssh_url":"git@github.com:smecsia/camelot.git","clone_url":"https://github.com/smecsia/camelot.git","svn_url":"https://github.com/smecsia/camelot","homepage":"http://camelot.qatools.ru","size":1433,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"camelot-framework:master","ref":"master","sha":"ec5a6bbc6496e3dd7198b796952bdac099bebbf8","user":{"login":"camelot-framework","id":6671821,"avatar_url":"https://avatars.githubusercontent.com/u/6671821?v=3","gravatar_id":"","url":"https://api.github.com/users/camelot-framework","html_url":"https://github.com/camelot-framework","followers_url":"https://api.github.com/users/camelot-framework/followers","following_url":"https://api.github.com/users/camelot-framework/following{/other_user}","gists_url":"https://api.github.com/users/camelot-framework/gists{/gist_id}","starred_url":"https://api.github.com/users/camelot-framework/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/camelot-framework/subscriptions","organizations_url":"https://api.github.com/users/camelot-framework/orgs","repos_url":"https://api.github.com/users/camelot-framework/repos","events_url":"https://api.github.com/users/camelot-framework/events{/privacy}","received_events_url":"https://api.github.com/users/camelot-framework/received_events","type":"Organization","site_admin":false},"repo":{"id":22441031,"name":"camelot","full_name":"camelot-framework/camelot","owner":{"login":"camelot-framework","id":6671821,"avatar_url":"https://avatars.githubusercontent.com/u/6671821?v=3","gravatar_id":"","url":"https://api.github.com/users/camelot-framework","html_url":"https://github.com/camelot-framework","followers_url":"https://api.github.com/users/camelot-framework/followers","following_url":"https://api.github.com/users/camelot-framework/following{/other_user}","gists_url":"https://api.github.com/users/camelot-framework/gists{/gist_id}","starred_url":"https://api.github.com/users/camelot-framework/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/camelot-framework/subscriptions","organizations_url":"https://api.github.com/users/camelot-framework/orgs","repos_url":"https://api.github.com/users/camelot-framework/repos","events_url":"https://api.github.com/users/camelot-framework/events{/privacy}","received_events_url":"https://api.github.com/users/camelot-framework/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/camelot-framework/camelot","description":"Simplified scalable aggregation and processing framework built upon Apache Camel.","fork":false,"url":"https://api.github.com/repos/camelot-framework/camelot","forks_url":"https://api.github.com/repos/camelot-framework/camelot/forks","keys_url":"https://api.github.com/repos/camelot-framework/camelot/keys{/key_id}","collaborators_url":"https://api.github.com/repos/camelot-framework/camelot/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/camelot-framework/camelot/teams","hooks_url":"https://api.github.com/repos/camelot-framework/camelot/hooks","issue_events_url":"https://api.github.com/repos/camelot-framework/camelot/issues/events{/number}","events_url":"https://api.github.com/repos/camelot-framework/camelot/events","assignees_url":"https://api.github.com/repos/camelot-framework/camelot/assignees{/user}","branches_url":"https://api.github.com/repos/camelot-framework/camelot/branches{/branch}","tags_url":"https://api.github.com/repos/camelot-framework/camelot/tags","blobs_url":"https://api.github.com/repos/camelot-framework/camelot/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/camelot-framework/camelot/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/camelot-framework/camelot/git/refs{/sha}","trees_url":"https://api.github.com/repos/camelot-framework/camelot/git/trees{/sha}","statuses_url":"https://api.github.com/repos/camelot-framework/camelot/statuses/{sha}","languages_url":"https://api.github.com/repos/camelot-framework/camelot/languages","stargazers_url":"https://api.github.com/repos/camelot-framework/camelot/stargazers","contributors_url":"https://api.github.com/repos/camelot-framework/camelot/contributors","subscribers_url":"https://api.github.com/repos/camelot-framework/camelot/subscribers","subscription_url":"https://api.github.com/repos/camelot-framework/camelot/subscription","commits_url":"https://api.github.com/repos/camelot-framework/camelot/commits{/sha}","git_commits_url":"https://api.github.com/repos/camelot-framework/camelot/git/commits{/sha}","comments_url":"https://api.github.com/repos/camelot-framework/camelot/comments{/number}","issue_comment_url":"https://api.github.com/repos/camelot-framework/camelot/issues/comments{/number}","contents_url":"https://api.github.com/repos/camelot-framework/camelot/contents/{+path}","compare_url":"https://api.github.com/repos/camelot-framework/camelot/compare/{base}...{head}","merges_url":"https://api.github.com/repos/camelot-framework/camelot/merges","archive_url":"https://api.github.com/repos/camelot-framework/camelot/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/camelot-framework/camelot/downloads","issues_url":"https://api.github.com/repos/camelot-framework/camelot/issues{/number}","pulls_url":"https://api.github.com/repos/camelot-framework/camelot/pulls{/number}","milestones_url":"https://api.github.com/repos/camelot-framework/camelot/milestones{/number}","notifications_url":"https://api.github.com/repos/camelot-framework/camelot/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/camelot-framework/camelot/labels{/name}","releases_url":"https://api.github.com/repos/camelot-framework/camelot/releases{/id}","created_at":"2014-07-30T19:06:12Z","updated_at":"2015-07-14T19:41:26Z","pushed_at":"2015-09-25T18:53:20Z","git_url":"git://github.com/camelot-framework/camelot.git","ssh_url":"git@github.com:camelot-framework/camelot.git","clone_url":"https://github.com/camelot-framework/camelot.git","svn_url":"https://github.com/camelot-framework/camelot","homepage":"","size":2127,"stargazers_count":10,"watchers_count":10,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":5,"mirror_url":null,"open_issues_count":3,"forks":5,"open_issues":3,"watchers":10,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/camelot-framework/camelot/pulls/95"},"html":{"href":"https://github.com/camelot-framework/camelot/pull/95"},"issue":{"href":"https://api.github.com/repos/camelot-framework/camelot/issues/95"},"comments":{"href":"https://api.github.com/repos/camelot-framework/camelot/issues/95/comments"},"review_comments":{"href":"https://api.github.com/repos/camelot-framework/camelot/pulls/95/comments"},"review_comment":{"href":"https://api.github.com/repos/camelot-framework/camelot/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/camelot-framework/camelot/pulls/95/commits"},"statuses":{"href":"https://api.github.com/repos/camelot-framework/camelot/statuses/60a16cd8c2933063603212890bbbcebdd1d41916"}}}}