/* (non-Javadoc)
  * @see org.eclipse.bpmn2.modeler.core.features.IFeatureContainer#getApplyObject(org.eclipse.graphiti.features.context.IContext)
  */
 @Override
 public Object getApplyObject(IContext context) {
   if (context instanceof IAddContext) {
     return ((IAddContext) context).getNewObject();
   } else if (context instanceof IPictogramElementContext) {
     return BusinessObjectUtil.getFirstElementOfType(
         (((IPictogramElementContext) context).getPictogramElement()), BaseElement.class);
   } else if (context instanceof IReconnectionContext) {
     IReconnectionContext rc = (IReconnectionContext) context;
     return BusinessObjectUtil.getFirstElementOfType(rc.getConnection(), BaseElement.class);
   } else if (context instanceof ICustomContext) {
     PictogramElement[] pes = ((ICustomContext) context).getPictogramElements();
     if (pes.length == 1)
       return BusinessObjectUtil.getFirstElementOfType(pes[0], BaseElement.class);
   }
   return null;
 }
 @Override
 public void postReconnect(IReconnectionContext context) {
   Object connectionObject =
       getFeatureProvider().getBusinessObjectForPictogramElement(context.getConnection());
   if (connectionObject instanceof MessageFlow) {
     FlowNode source = null;
     FlowNode target = null;
     MessageFlow messageFlow = (MessageFlow) connectionObject;
     BpmnMemoryModel memoryModel = ModelHandler.getModel(EcoreUtil.getURI(getDiagram()));
     memoryModel.getBpmnModel().getMessageFlows().remove(messageFlow);
     if (context.getReconnectType().equalsIgnoreCase(ReconnectionContext.RECONNECT_TARGET)) {
       source = getFlowNode(context.getConnection().getStart());
       target = getFlowNode(context.getNewAnchor());
     } else {
       source = getFlowNode(context.getNewAnchor());
       target = getFlowNode(context.getConnection().getEnd());
     }
     messageFlow.setSourceRef(source.getId());
     messageFlow.setTargetRef(target.getId());
     memoryModel.getBpmnModel().getMessageFlows().add(messageFlow);
     undoedSource = messageFlow.getSourceRef();
     undoedTarget = messageFlow.getTargetRef();
   } else {
     return;
   }
   super.postReconnect(context);
 }
  @Override
  public boolean canReconnect(IReconnectionContext context) {
    FlowNode source = null;
    FlowNode target = null;
    Object target2 = null;
    Object targetContainer = null;
    Object targetContainer2 = null;
    Object sourceContainer = null;
    Object targetContainerParent = null;
    Object sourceContainerParent = null;
    Object sourceContainerParent2 = null;
    if (context.getReconnectType().equals(ReconnectionContext.RECONNECT_TARGET)) {
      source = getFlowNode(context.getConnection().getStart());
      target = getFlowNode(context.getNewAnchor());
      targetContainer =
          getBusinessObjectForPictogramElement(
              (PictogramElement) context.getNewAnchor().getParent().eContainer());
      sourceContainer =
          getBusinessObjectForPictogramElement(
              (PictogramElement) context.getConnection().getStart().eContainer().eContainer());
      targetContainerParent =
          getBusinessObjectForPictogramElement(
              (PictogramElement) context.getNewAnchor().getParent().eContainer().eContainer());
      sourceContainerParent =
          getBusinessObjectForPictogramElement(
              (PictogramElement)
                  context.getConnection().getStart().getParent().eContainer().eContainer());
      // sourceContainerParent2 =
      // getBusinessObjectForPictogramElement((PictogramElement)context.getConnection().getStart().getParent().eContainer().eContainer().eContainer());
      // sourceContainerParent2 =
      // getBusinessObjectForPictogramElement((PictogramElement)context.getConnection().getStart().getParent().eContainer().eContainer().eContainer());
    } else {
      source = getFlowNode(context.getNewAnchor());
      target = getFlowNode(context.getConnection().getEnd());
      targetContainer =
          getBusinessObjectForPictogramElement(
              (PictogramElement) context.getConnection().getEnd().eContainer().eContainer());
      targetContainer2 =
          getBusinessObjectForPictogramElement(
              (PictogramElement) context.getConnection().getStart().eContainer().eContainer());
      sourceContainer =
          getBusinessObjectForPictogramElement(
              (PictogramElement) context.getNewAnchor().getParent().eContainer());
      targetContainerParent =
          getBusinessObjectForPictogramElement(
              (PictogramElement)
                  context.getConnection().getEnd().getParent().eContainer().eContainer());
      sourceContainerParent =
          getBusinessObjectForPictogramElement(
              (PictogramElement) context.getNewAnchor().getParent().eContainer().eContainer());
      // sourceContainerParent2 =
      // getBusinessObjectForPictogramElement((PictogramElement)context.getNewAnchor().getParent().eContainer().eContainer().eContainer());
    }

    if (source != null && target != null && source != target) {
      BpmnMemoryModel memoryModel = ModelHandler.getModel(EcoreUtil.getURI(getDiagram()));
      Process sourceProcess = null;
      Process targetProcess = null;
      for (Process proc : memoryModel.getBpmnModel().getProcesses()) {
        if (proc.getFlowElement(source.getId()) != null) {
          sourceProcess = proc;
        }
        if (proc.getFlowElement(target.getId()) != null) {
          targetProcess = proc;
        }
      }

      /*if(context.getReconnectType().equals(ReconnectionContext.RECONNECT_TARGET)
      		&& sourceContainer instanceof SubProcess
      		&& target instanceof SubProcess){
      	return true;
      }*/

      // **New rules - SZ
      if (source instanceof ServiceTask
          || source instanceof UserTask
          || source instanceof ScriptTask
          || target instanceof ServiceTask
          || target instanceof UserTask
          || target instanceof ScriptTask
          || source instanceof ReceiveTask
          || source instanceof StartEvent
          // || source instanceof BoundaryEvent &&
          // ((BoundaryEvent)source).getEventDefinitions().get(0) instanceof MessageEventDefinition
          || target instanceof SendTask
          // || source instanceof IntermediateCatchEvent &&
          // ((IntermediateCatchEvent)source).getEventDefinitions().get(0) instanceof
          // MessageEventDefinition
          || target instanceof StartEvent
              && !(((StartEvent) target).getEventDefinitions().get(0)
                  instanceof MessageEventDefinition)) {
        return false;
      }
      // **

      // System.out.println("SOURCE PROC: "+sourceProcess.getId());
      // System.out.println("TARGET PROC: "+targetProcess.getId());

      if (!(context.getReconnectType().equals(ReconnectionContext.RECONNECT_TARGET))
          && targetContainerParent != sourceContainerParent
          && targetContainer != sourceContainer
          && targetContainer != sourceContainerParent
          && targetContainerParent != sourceContainer) {
        if (source instanceof SendTask
            || source instanceof EndEvent
                && ((EndEvent) source).getEventDefinitions().get(0)
                    instanceof MessageEventDefinition
            || source instanceof IntermediateThrowEvent
                && ((IntermediateThrowEvent) source).getEventDefinitions().get(0)
                    instanceof MessageEventDefinition) {
          return true;
        }
      }

      // **SubProcess bug fixes -SZ
      if (targetProcess == null && target.getId() != null) {
        if (sourceProcess != null
            && targetContainerParent != sourceContainerParent
            && sourceContainer != targetContainerParent
            && targetContainer instanceof SubProcess) {
          if (target instanceof StartEvent
              || target instanceof ReceiveTask
              || target instanceof CatchEvent) {
            return true;
          }
        }
      }
      // **

      if (!(sourceContainer instanceof SubProcess)) {
        if (sourceProcess == null || targetProcess == null || sourceProcess == targetProcess) {
          return false;
        }
      } else if (sourceContainerParent == targetContainer) {
        return false;
      } else if (context.getReconnectType().equals(ReconnectionContext.RECONNECT_TARGET)) {
        if (sourceContainer instanceof SubProcess && sourceContainer != targetContainer) {
        } else {
          sourceContainerParent =
              getBusinessObjectForPictogramElement(
                  (PictogramElement) context.getNewAnchor().getParent().eContainer().eContainer());
          sourceContainerParent2 =
              getBusinessObjectForPictogramElement(
                  (PictogramElement)
                      context.getNewAnchor().getParent().eContainer().eContainer().eContainer());
          if (sourceContainerParent2 == targetContainerParent
              || targetContainer == sourceContainer) {
            return false;
          }
        }
      } else if (sourceContainer instanceof SubProcess) {
        return false;
      }

      if (source instanceof Task
          || source instanceof SubProcess
          || (source instanceof IntermediateThrowEvent
              && ((IntermediateThrowEvent) source).getEventDefinitions().get(0)
                  instanceof MessageEventDefinition)
          || (source instanceof EndEvent
              && ((EndEvent) source).getEventDefinitions().get(0)
                  instanceof MessageEventDefinition)) {
        if (target instanceof Task
            || (target instanceof IntermediateCatchEvent
                && ((IntermediateCatchEvent) target).getEventDefinitions().get(0)
                    instanceof MessageEventDefinition)
            || (source instanceof StartEvent
                && ((StartEvent) source).getEventDefinitions().get(0)
                    instanceof MessageEventDefinition)
            || target instanceof SubProcess
            || target instanceof StartEvent
            || (target instanceof BoundaryEvent
                && ((BoundaryEvent) target).getEventDefinitions().get(0)
                    instanceof MessageEventDefinition)) {
          return true;
        } else {
          return false;
        }
      }
      return false;
    } else {
      return false;
    }
  }
 @Override
 public void preReconnect(IReconnectionContext context) {
   sourceStart = getFlowNode(context.getConnection().getStart());
   sourceEnd = getFlowNode(context.getConnection().getEnd());
 }