void CModelExpansion::duplicateEvent(CEvent* source, const std::string & index, const SetOfModelElements & sourceSet, ElementsMap & emap) { //if the source object has already been duplicated: do nothing if (emap.exists(source)) return; CEvent* newObj = NULL; if (expressionContainsObject(source->getTriggerExpressionPtr(), sourceSet) || expressionContainsObject(source->getDelayExpressionPtr(), sourceSet)) { //we need to duplicate the event itself (because the trigger refers to a duplicated object) //try creating the object until we find a name that is not yet used std::ostringstream infix; do { std::ostringstream name; name << source->getObjectName() << infix.str() << index; newObj = mpModel->createEvent(name.str()); infix << "_"; } while (!newObj); //add duplicated object to the map emap.add(source, newObj); //now do the trigger newObj->setTriggerExpression(source->getTriggerExpression()); newObj->getTriggerExpressionPtr()->compile(); //I don't know why this is necessary updateExpression(newObj->getTriggerExpressionPtr(), index, sourceSet, emap); //delay newObj->setDelayExpression(source->getDelayExpression()); newObj->getDelayExpressionPtr()->compile(); //I don't know why this is necessary updateExpression(newObj->getDelayExpressionPtr(), index, sourceSet, emap); newObj->setDelayAssignment(source->getDelayAssignment()); } else { newObj = source; //no copying necessary //add duplicated object to the map emap.add(source, newObj); } //now the event assignments... size_t i; for (i = 0; i < source->getAssignments().size(); ++i) { const CEventAssignment* pSourceAssignment = source->getAssignments()[i]; //const CModelEntity * pSourceTarget = dynamic_cast<const CModelEntity * >(CCopasiRootContainer::getKeyFactory()->get(pSourceAssignment->getTargetKey())); if (sourceSet.contains(pSourceAssignment->getTargetKey())) { //we assume that the duplicate of the target object already exists. //this should be true since events are duplicated last. if (!emap.exists(pSourceAssignment->getTargetKey())) continue; //create duplicate of assignment (this can be either in the original event or in the //duplicate of an event) CEventAssignment * pNewAssignment = new CEventAssignment(emap.getDuplicateKey(pSourceAssignment->getTargetKey())); newObj->getAssignments().add(pNewAssignment, true); //we do an assumption: //It should not happen that the assignment expression contains a reference to an object that is duplicated, //but the assignment target is not duplicated. //now copy the expression pNewAssignment->setExpression(pSourceAssignment->getExpression()); pNewAssignment->getExpressionPtr()->compile(); updateExpression(pNewAssignment->getExpressionPtr(), index, sourceSet, emap); } } newObj->setNotes(source->getNotes()); newObj->setMiriamAnnotation(source->getMiriamAnnotation(), newObj->getKey(), source->getKey()); }