void AMScanActionControllerScanAssembler::generateActionTree(){
	actionTree_ = generateActionTreeForAxis(controls_->at(0), axes_.at(0));

	QList<AMAction3*> insertionPoints = findInsertionPoints(actionTree_);
	for(int x = 1; x < axes_.count(); x++){
		QList<AMAction3*> newInsertionPoints;
		newInsertionPoints.clear();

		for(int y = 0; y < insertionPoints.count(); y++){
			AMListAction3 *castParentToListAction = qobject_cast<AMListAction3*>(insertionPoints.at(y)->parentAction());
			if(castParentToListAction){
				int indexOfAction = castParentToListAction->indexOfSubAction(insertionPoints.at(y));
				castParentToListAction->insertSubAction(generateActionTreeForAxis(controls_->at(x), axes_.at(x)), indexOfAction);
				castParentToListAction->deleteSubAction(indexOfAction+1);
				newInsertionPoints.append(findInsertionPoints(castParentToListAction->subActionAt(indexOfAction)));
			}
		}
		insertionPoints.clear();
		insertionPoints = newInsertionPoints;
	}

	QList<AMAction3*> detectorInsertionPoints = findInsertionPoints(actionTree_);
	for(int x = 0; x < detectorInsertionPoints.count(); x++){
		AMListAction3 *castParentToListAction = qobject_cast<AMListAction3*>(detectorInsertionPoints.at(x)->parentAction());
		if(castParentToListAction){
			int indexOfAction = castParentToListAction->indexOfSubAction(detectorInsertionPoints.at(x));
			castParentToListAction->insertSubAction(generateActionListForDetectorAcquisition(), indexOfAction);
			castParentToListAction->deleteSubAction(indexOfAction+1);
		}
	}

	AMListAction3 *castRetValToListAction = qobject_cast<AMListAction3*>(actionTree_);
	if(castRetValToListAction){
		AMListAction3 *castFirstToListAction = qobject_cast<AMListAction3*>(castRetValToListAction->subActionAt(1));
		if(castFirstToListAction)
			castFirstToListAction->addSubAction(generateActionListForDetectorInitialization());

		AMListAction3 *castLastToListAction = qobject_cast<AMListAction3*>(castRetValToListAction->subActionAt(castRetValToListAction->subActionCount()-2));
		if(castLastToListAction)
			castLastToListAction->addSubAction(generateActionListForDetectorCleanup());
	}

	emit actionTreeGenerated(actionTree_);
}
void AMSingleElementListOptimizer::optimizeImplementation(AMAction3 *scanActionTree){
	AMListAction3 *templateListAction = new AMListAction3(new AMListActionInfo3("Fake List", "Fake List"));
	QList<AMAction3*> allListsAsActions = AMScanActionTreeSupport::findActionsOfType(scanActionTree, templateListAction);

	QList<AMListAction3*> allLists;
	AMListAction3 *tempListAction;
	for(int x = 0; x < allListsAsActions.count(); x++){
		tempListAction = qobject_cast<AMListAction3*>(allListsAsActions.at(x));
		if(tempListAction)
			allLists.append(tempListAction);
	}

	for(int x = 0; x < allLists.count(); x++){
		if(allLists.at(x)->subActionCount() == 1){
			AMListAction3 *castParentToList = qobject_cast<AMListAction3*>(allLists.at(x)->parentAction());
			if(castParentToList){
				int indexOfThisList = castParentToList->indexOfSubAction(allLists.at(x));
				castParentToList->insertSubAction(allLists.at(x)->takeSubActionAt(0), indexOfThisList);
				castParentToList->deleteSubAction(castParentToList->indexOfSubAction(allLists.at(x)));
			}
		}
	}
}
void AMEmptyListScanOptimizer::optimizeImplementation(AMAction3 *scanActionTree){
	AMListAction3 *templateListAction = new AMListAction3(new AMListActionInfo3("Fake List", "Fake List"));
	QList<AMAction3*> allListsAsActions = AMScanActionTreeSupport::findActionsOfType(scanActionTree, templateListAction);

	QList<AMListAction3*> allLists;
	AMListAction3 *tempListAction;
	for(int x = 0; x < allListsAsActions.count(); x++){
		tempListAction = qobject_cast<AMListAction3*>(allListsAsActions.at(x));
		if(tempListAction)
			allLists.append(tempListAction);
	}

	for(int x = 0; x < allLists.count(); x++){
		if(allLists.at(x)->subActionCount() == 0){
			AMListAction3 *castParentToList = qobject_cast<AMListAction3*>(allLists.at(x)->parentAction());
			if(castParentToList)
				castParentToList->deleteSubAction(castParentToList->indexOfSubAction(allLists.at(x)));
		}
	}

	templateListAction->deleteLater();
}