{"action":"created","comment":{"url":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls/comments/37646288","id":37646288,"diff_hunk":"@@ -67,16 +68,44 @@ public boolean isConstraintMatchEnabled() {\n     // Worker methods\n     // ************************************************************************\n \n+    protected class MultiLevelConstraintUndoListener implements ActivationUnMatchListener {\n+\n+        private Map<Integer, ActivationUnMatchListener> activationUnMatchListenerMap;\n+\n+        public MultiLevelConstraintUndoListener(int scoreLevel, ActivationUnMatchListener activationUnMatchListener) {\n+            this.activationUnMatchListenerMap = new HashMap<Integer, ActivationUnMatchListener>();\n+            match(scoreLevel, activationUnMatchListener);\n+        }\n+\n+        @Override\n+        public final void unMatch(RuleRuntime ruleRuntime, Match match) {\n+            for (Integer scoreLevel : activationUnMatchListenerMap.keySet()) {\n+                unMatch(scoreLevel);\n+            }\n+        }\n+\n+        public void unMatch(int scoreLevel) {\n+            if (activationUnMatchListenerMap.containsKey(scoreLevel)) {\n+                // Both parameters null because they are not used by the ActivationUnMatchListener created anyway\n+                activationUnMatchListenerMap.get(scoreLevel).unMatch(null, null);\n+                activationUnMatchListenerMap.remove(scoreLevel);","path":"optaplanner-core/src/main/java/org/optaplanner/core/api/score/holder/AbstractScoreHolder.java","position":32,"original_position":32,"commit_id":"a39e94972963e620cc584afd46948d287d90b218","original_commit_id":"a39e94972963e620cc584afd46948d287d90b218","user":{"login":"oskopek","id":1811716,"avatar_url":"https://avatars.githubusercontent.com/u/1811716?v=3","gravatar_id":"","url":"https://api.github.com/users/oskopek","html_url":"https://github.com/oskopek","followers_url":"https://api.github.com/users/oskopek/followers","following_url":"https://api.github.com/users/oskopek/following{/other_user}","gists_url":"https://api.github.com/users/oskopek/gists{/gist_id}","starred_url":"https://api.github.com/users/oskopek/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/oskopek/subscriptions","organizations_url":"https://api.github.com/users/oskopek/orgs","repos_url":"https://api.github.com/users/oskopek/repos","events_url":"https://api.github.com/users/oskopek/events{/privacy}","received_events_url":"https://api.github.com/users/oskopek/received_events","type":"User","site_admin":false},"body":"Agreed, performance > re-usability in this case.","created_at":"2015-08-21T15:35:05Z","updated_at":"2015-08-21T15:35:05Z","html_url":"https://github.com/droolsjbpm/optaplanner/pull/128#discussion_r37646288","pull_request_url":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls/128","_links":{"self":{"href":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls/comments/37646288"},"html":{"href":"https://github.com/droolsjbpm/optaplanner/pull/128#discussion_r37646288"},"pull_request":{"href":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls/128"}}},"pull_request":{"url":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls/128","id":42816650,"html_url":"https://github.com/droolsjbpm/optaplanner/pull/128","diff_url":"https://github.com/droolsjbpm/optaplanner/pull/128.diff","patch_url":"https://github.com/droolsjbpm/optaplanner/pull/128.patch","issue_url":"https://api.github.com/repos/droolsjbpm/optaplanner/issues/128","number":128,"state":"open","locked":false,"title":"PLANNER-284: Ability to report multiple scores from a single rule","user":{"login":"oskopek","id":1811716,"avatar_url":"https://avatars.githubusercontent.com/u/1811716?v=3","gravatar_id":"","url":"https://api.github.com/users/oskopek","html_url":"https://github.com/oskopek","followers_url":"https://api.github.com/users/oskopek/followers","following_url":"https://api.github.com/users/oskopek/following{/other_user}","gists_url":"https://api.github.com/users/oskopek/gists{/gist_id}","starred_url":"https://api.github.com/users/oskopek/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/oskopek/subscriptions","organizations_url":"https://api.github.com/users/oskopek/orgs","repos_url":"https://api.github.com/users/oskopek/repos","events_url":"https://api.github.com/users/oskopek/events{/privacy}","received_events_url":"https://api.github.com/users/oskopek/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-08-19T13:53:12Z","updated_at":"2015-08-21T15:35:05Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c3229b48a9b86127276cd7ef66b7456968e383f3","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls/128/commits","review_comments_url":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls/128/comments","review_comment_url":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls/comments{/number}","comments_url":"https://api.github.com/repos/droolsjbpm/optaplanner/issues/128/comments","statuses_url":"https://api.github.com/repos/droolsjbpm/optaplanner/statuses/a39e94972963e620cc584afd46948d287d90b218","head":{"label":"oskopek:PLANNER-284","ref":"PLANNER-284","sha":"a39e94972963e620cc584afd46948d287d90b218","user":{"login":"oskopek","id":1811716,"avatar_url":"https://avatars.githubusercontent.com/u/1811716?v=3","gravatar_id":"","url":"https://api.github.com/users/oskopek","html_url":"https://github.com/oskopek","followers_url":"https://api.github.com/users/oskopek/followers","following_url":"https://api.github.com/users/oskopek/following{/other_user}","gists_url":"https://api.github.com/users/oskopek/gists{/gist_id}","starred_url":"https://api.github.com/users/oskopek/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/oskopek/subscriptions","organizations_url":"https://api.github.com/users/oskopek/orgs","repos_url":"https://api.github.com/users/oskopek/repos","events_url":"https://api.github.com/users/oskopek/events{/privacy}","received_events_url":"https://api.github.com/users/oskopek/received_events","type":"User","site_admin":false},"repo":{"id":11878050,"name":"optaplanner","full_name":"oskopek/optaplanner","owner":{"login":"oskopek","id":1811716,"avatar_url":"https://avatars.githubusercontent.com/u/1811716?v=3","gravatar_id":"","url":"https://api.github.com/users/oskopek","html_url":"https://github.com/oskopek","followers_url":"https://api.github.com/users/oskopek/followers","following_url":"https://api.github.com/users/oskopek/following{/other_user}","gists_url":"https://api.github.com/users/oskopek/gists{/gist_id}","starred_url":"https://api.github.com/users/oskopek/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/oskopek/subscriptions","organizations_url":"https://api.github.com/users/oskopek/orgs","repos_url":"https://api.github.com/users/oskopek/repos","events_url":"https://api.github.com/users/oskopek/events{/privacy}","received_events_url":"https://api.github.com/users/oskopek/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/oskopek/optaplanner","description":"OptaPlanner optimizes business resource scheduling and planning.","fork":true,"url":"https://api.github.com/repos/oskopek/optaplanner","forks_url":"https://api.github.com/repos/oskopek/optaplanner/forks","keys_url":"https://api.github.com/repos/oskopek/optaplanner/keys{/key_id}","collaborators_url":"https://api.github.com/repos/oskopek/optaplanner/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/oskopek/optaplanner/teams","hooks_url":"https://api.github.com/repos/oskopek/optaplanner/hooks","issue_events_url":"https://api.github.com/repos/oskopek/optaplanner/issues/events{/number}","events_url":"https://api.github.com/repos/oskopek/optaplanner/events","assignees_url":"https://api.github.com/repos/oskopek/optaplanner/assignees{/user}","branches_url":"https://api.github.com/repos/oskopek/optaplanner/branches{/branch}","tags_url":"https://api.github.com/repos/oskopek/optaplanner/tags","blobs_url":"https://api.github.com/repos/oskopek/optaplanner/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/oskopek/optaplanner/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/oskopek/optaplanner/git/refs{/sha}","trees_url":"https://api.github.com/repos/oskopek/optaplanner/git/trees{/sha}","statuses_url":"https://api.github.com/repos/oskopek/optaplanner/statuses/{sha}","languages_url":"https://api.github.com/repos/oskopek/optaplanner/languages","stargazers_url":"https://api.github.com/repos/oskopek/optaplanner/stargazers","contributors_url":"https://api.github.com/repos/oskopek/optaplanner/contributors","subscribers_url":"https://api.github.com/repos/oskopek/optaplanner/subscribers","subscription_url":"https://api.github.com/repos/oskopek/optaplanner/subscription","commits_url":"https://api.github.com/repos/oskopek/optaplanner/commits{/sha}","git_commits_url":"https://api.github.com/repos/oskopek/optaplanner/git/commits{/sha}","comments_url":"https://api.github.com/repos/oskopek/optaplanner/comments{/number}","issue_comment_url":"https://api.github.com/repos/oskopek/optaplanner/issues/comments{/number}","contents_url":"https://api.github.com/repos/oskopek/optaplanner/contents/{+path}","compare_url":"https://api.github.com/repos/oskopek/optaplanner/compare/{base}...{head}","merges_url":"https://api.github.com/repos/oskopek/optaplanner/merges","archive_url":"https://api.github.com/repos/oskopek/optaplanner/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/oskopek/optaplanner/downloads","issues_url":"https://api.github.com/repos/oskopek/optaplanner/issues{/number}","pulls_url":"https://api.github.com/repos/oskopek/optaplanner/pulls{/number}","milestones_url":"https://api.github.com/repos/oskopek/optaplanner/milestones{/number}","notifications_url":"https://api.github.com/repos/oskopek/optaplanner/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/oskopek/optaplanner/labels{/name}","releases_url":"https://api.github.com/repos/oskopek/optaplanner/releases{/id}","created_at":"2013-08-04T12:08:28Z","updated_at":"2015-06-26T11:02:58Z","pushed_at":"2015-08-21T14:50:28Z","git_url":"git://github.com/oskopek/optaplanner.git","ssh_url":"git@github.com:oskopek/optaplanner.git","clone_url":"https://github.com/oskopek/optaplanner.git","svn_url":"https://github.com/oskopek/optaplanner","homepage":"http://www.optaplanner.org","size":147905,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"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":"droolsjbpm:master","ref":"master","sha":"9c965ad93591243ebdbd5a543df810503fed626b","user":{"login":"droolsjbpm","id":517980,"avatar_url":"https://avatars.githubusercontent.com/u/517980?v=3","gravatar_id":"","url":"https://api.github.com/users/droolsjbpm","html_url":"https://github.com/droolsjbpm","followers_url":"https://api.github.com/users/droolsjbpm/followers","following_url":"https://api.github.com/users/droolsjbpm/following{/other_user}","gists_url":"https://api.github.com/users/droolsjbpm/gists{/gist_id}","starred_url":"https://api.github.com/users/droolsjbpm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/droolsjbpm/subscriptions","organizations_url":"https://api.github.com/users/droolsjbpm/orgs","repos_url":"https://api.github.com/users/droolsjbpm/repos","events_url":"https://api.github.com/users/droolsjbpm/events{/privacy}","received_events_url":"https://api.github.com/users/droolsjbpm/received_events","type":"Organization","site_admin":false},"repo":{"id":1370858,"name":"optaplanner","full_name":"droolsjbpm/optaplanner","owner":{"login":"droolsjbpm","id":517980,"avatar_url":"https://avatars.githubusercontent.com/u/517980?v=3","gravatar_id":"","url":"https://api.github.com/users/droolsjbpm","html_url":"https://github.com/droolsjbpm","followers_url":"https://api.github.com/users/droolsjbpm/followers","following_url":"https://api.github.com/users/droolsjbpm/following{/other_user}","gists_url":"https://api.github.com/users/droolsjbpm/gists{/gist_id}","starred_url":"https://api.github.com/users/droolsjbpm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/droolsjbpm/subscriptions","organizations_url":"https://api.github.com/users/droolsjbpm/orgs","repos_url":"https://api.github.com/users/droolsjbpm/repos","events_url":"https://api.github.com/users/droolsjbpm/events{/privacy}","received_events_url":"https://api.github.com/users/droolsjbpm/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/droolsjbpm/optaplanner","description":"Java planning engine: OptaPlanner optimizes business resource scheduling and planning.","fork":false,"url":"https://api.github.com/repos/droolsjbpm/optaplanner","forks_url":"https://api.github.com/repos/droolsjbpm/optaplanner/forks","keys_url":"https://api.github.com/repos/droolsjbpm/optaplanner/keys{/key_id}","collaborators_url":"https://api.github.com/repos/droolsjbpm/optaplanner/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/droolsjbpm/optaplanner/teams","hooks_url":"https://api.github.com/repos/droolsjbpm/optaplanner/hooks","issue_events_url":"https://api.github.com/repos/droolsjbpm/optaplanner/issues/events{/number}","events_url":"https://api.github.com/repos/droolsjbpm/optaplanner/events","assignees_url":"https://api.github.com/repos/droolsjbpm/optaplanner/assignees{/user}","branches_url":"https://api.github.com/repos/droolsjbpm/optaplanner/branches{/branch}","tags_url":"https://api.github.com/repos/droolsjbpm/optaplanner/tags","blobs_url":"https://api.github.com/repos/droolsjbpm/optaplanner/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/droolsjbpm/optaplanner/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/droolsjbpm/optaplanner/git/refs{/sha}","trees_url":"https://api.github.com/repos/droolsjbpm/optaplanner/git/trees{/sha}","statuses_url":"https://api.github.com/repos/droolsjbpm/optaplanner/statuses/{sha}","languages_url":"https://api.github.com/repos/droolsjbpm/optaplanner/languages","stargazers_url":"https://api.github.com/repos/droolsjbpm/optaplanner/stargazers","contributors_url":"https://api.github.com/repos/droolsjbpm/optaplanner/contributors","subscribers_url":"https://api.github.com/repos/droolsjbpm/optaplanner/subscribers","subscription_url":"https://api.github.com/repos/droolsjbpm/optaplanner/subscription","commits_url":"https://api.github.com/repos/droolsjbpm/optaplanner/commits{/sha}","git_commits_url":"https://api.github.com/repos/droolsjbpm/optaplanner/git/commits{/sha}","comments_url":"https://api.github.com/repos/droolsjbpm/optaplanner/comments{/number}","issue_comment_url":"https://api.github.com/repos/droolsjbpm/optaplanner/issues/comments{/number}","contents_url":"https://api.github.com/repos/droolsjbpm/optaplanner/contents/{+path}","compare_url":"https://api.github.com/repos/droolsjbpm/optaplanner/compare/{base}...{head}","merges_url":"https://api.github.com/repos/droolsjbpm/optaplanner/merges","archive_url":"https://api.github.com/repos/droolsjbpm/optaplanner/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/droolsjbpm/optaplanner/downloads","issues_url":"https://api.github.com/repos/droolsjbpm/optaplanner/issues{/number}","pulls_url":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls{/number}","milestones_url":"https://api.github.com/repos/droolsjbpm/optaplanner/milestones{/number}","notifications_url":"https://api.github.com/repos/droolsjbpm/optaplanner/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/droolsjbpm/optaplanner/labels{/name}","releases_url":"https://api.github.com/repos/droolsjbpm/optaplanner/releases{/id}","created_at":"2011-02-15T19:38:23Z","updated_at":"2015-08-20T12:27:55Z","pushed_at":"2015-08-21T14:53:21Z","git_url":"git://github.com/droolsjbpm/optaplanner.git","ssh_url":"git@github.com:droolsjbpm/optaplanner.git","clone_url":"https://github.com/droolsjbpm/optaplanner.git","svn_url":"https://github.com/droolsjbpm/optaplanner","homepage":"http://www.optaplanner.org","size":173604,"stargazers_count":294,"watchers_count":294,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":210,"mirror_url":null,"open_issues_count":4,"forks":210,"open_issues":4,"watchers":294,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls/128"},"html":{"href":"https://github.com/droolsjbpm/optaplanner/pull/128"},"issue":{"href":"https://api.github.com/repos/droolsjbpm/optaplanner/issues/128"},"comments":{"href":"https://api.github.com/repos/droolsjbpm/optaplanner/issues/128/comments"},"review_comments":{"href":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls/128/comments"},"review_comment":{"href":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls/128/commits"},"statuses":{"href":"https://api.github.com/repos/droolsjbpm/optaplanner/statuses/a39e94972963e620cc584afd46948d287d90b218"}}}}