/* Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.camunda.bpm.engine.impl.migration;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.camunda.bpm.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
import org.camunda.bpm.engine.impl.pvm.process.ActivityImpl;
import org.camunda.bpm.engine.impl.pvm.process.ProcessDefinitionImpl;
import org.camunda.bpm.engine.impl.pvm.process.ScopeImpl;
import org.camunda.bpm.engine.migration.MigrationInstruction;

/**
 * @author Thorben Lindhauer
 *
 */
public class DefaultMigrationPlanGenerator implements MigrationInstructionGenerator {

  @Override
  public List<MigrationInstruction> generate(ProcessDefinitionImpl sourceProcessDefinition, ProcessDefinitionImpl targetProcessDefinition) {
    return generateInstructionsInScope(sourceProcessDefinition, targetProcessDefinition);
  }

  protected List<MigrationInstruction> generateInstructionsInScope(ScopeImpl sourceScope, ScopeImpl targetScope) {
    List<MigrationInstruction> instructions = new ArrayList<MigrationInstruction>();

    for (ActivityImpl sourceActivity : sourceScope.getActivities()) {
      for (ActivityImpl targetActivity : targetScope.getActivities()) {
        if (areEqualScopes(sourceActivity, targetActivity)) {
          instructions.addAll(generateInstructionsInScope(sourceActivity, targetActivity));
        }
        else if (areEqualActivities(sourceActivity, targetActivity)) {
          instructions.add(new MigrationInstructionImpl(
              Arrays.asList(sourceActivity.getId()), Arrays.asList(targetActivity.getId())));
        }
      }
    }

    return instructions;
  }

  protected boolean areEqualScopes(ScopeImpl sourceScope, ScopeImpl targetScope) {

    boolean areScopes = !sourceScope.getActivities().isEmpty() && !targetScope.getActivities().isEmpty();
    boolean matchingIds = sourceScope.getId().equals(targetScope.getId());
    boolean matchingTypes = (sourceScope == sourceScope.getProcessDefinition() && targetScope == targetScope.getProcessDefinition())
        || (sourceScope.getActivityBehavior().getClass() == targetScope.getActivityBehavior().getClass());

    return matchingIds && matchingTypes && areScopes;
  }

  protected boolean areEqualActivities(ActivityImpl sourceActivity, ActivityImpl targetActivity) {
    boolean matchingIds = sourceActivity.getId().equals(targetActivity.getId());

    boolean matchingTypes = sourceActivity.getActivityBehavior() instanceof UserTaskActivityBehavior
        && targetActivity.getActivityBehavior() instanceof UserTaskActivityBehavior;

    return matchingIds && matchingTypes;
  }

}

@@ -628,32 +628,39 @@
 rayList;%0Aimport 
+static 
 java.util.Arrays
@@ -653,21 +653,58 @@
 va.util.
-Array
+Collections.*;%0Aimport java.util.Collection
 s;%0Aimpor
@@ -1180,20 +1180,8 @@
  %7B%0A%0A
-  @Override%0A
   pu
@@ -1687,19 +1687,37 @@
 ) %7B%0A
+%0A
       
-for (
+// matching IDs%0A      
 Acti
@@ -1740,17 +1740,17 @@
 ctivity 
-:
+=
  targetS
@@ -1753,36 +1753,95 @@
 getScope.get
+Child
 Activit
-ies()
+y(sourceActivity.getId());%0A%0A      if(targetActivity != null
 ) %7B%0A        
@@ -2138,25 +2138,25 @@
         
-Arrays.as
+singleton
 List(sou
@@ -2180,18 +2180,32 @@
 ()),
- Arrays.as
+%0A              singleton
 List
@@ -2481,83 +2481,8 @@
 ();%0A
-    boolean matchingIds = sourceScope.getId().equals(targetScope.getId());%0A
     
@@ -2724,39 +2724,24 @@
 %0A%0A    return
- matchingIds &&
  matchingTyp
@@ -2864,89 +2864,8 @@
 y) %7B
-%0A    boolean matchingIds = sourceActivity.getId().equals(targetActivity.getId());
 %0A%0A  
@@ -3049,16 +3049,16 @@
 avior;%0A%0A
+
     retu
@@ -3063,23 +3063,8 @@
 turn
- matchingIds &&
  mat

improve efficiency of migration plan generator