InstanceSpecification::~InstanceSpecification()
{
//	cerr << "~InstanceSpecification "<<_name << endl;
	shared_ptr<Class> c=getClassifier();
	if (c)
		c->_removeInstance(this);
}
void InstanceSpecification::_createInstanceFromClass()
{
	shared_ptr<Class> c=getClassifier();
	if (c)
	{
		const map<string,shared_ptr<Property> >& prop=c->getAttributes();
		map<string,shared_ptr<Property> >::const_iterator it;
		for (it=prop.begin();it!=prop.end();it++)
		{
			Slot *s;
			if (it->second->getIsDerived())
				s=new SlotDerived(this, it->second) ;
			else
				s=new Slot(this, it->second) ;
			_slots.insert(make_pair(it->first,shared_ptr<Slot>(s)));
		}

/*
				Classifier::OwnedBehaviorMap behaviors = _classifier->getOwnedBehavior();
				map<string, shared_ptr<Behavior> >::iterator itB;
				for (itB = behaviors.begin(); itB != behaviors.end(); itB++)
				{
				   shared_ptr<Behavior> behavior = itB->second;
				   shared_ptr<InstanceSpecification> host = shared_dynamic_cast<InstanceSpecification>(shared_from_this());
				   BehaviorScheduler::getInstance()->executeBehavior(behavior,host,Parameters());
				}
		 */
	}
}
InstanceSpecification::InstanceSpecification(const string& name,shared_ptr<Class> cl):
							Element(name),_classifier(cl)
{
	shared_ptr<Class> c=getClassifier();
	if (c)
	{
		_createInstanceFromClass();
		string newName=c->_addInstance(this);
		setName(newName);
		c->fireCBOnCreate(this);
	}
}
void ClassifierConfiguration::writeToCSV(ClassifierOutput *clOutput){
    extern pthread_mutex_t csv_mutex;

    string csvFilename("classifier-benchmark.csv");
    pthread_mutex_lock(&csv_mutex);
    bool printHeader = !fileExists(csvFilename);
    ofstream output(csvFilename, fstream::app);
    if(printHeader) {
        output << "Nr.;Classifier;Transformers;Feature Selector;Trainingset/Testset Ratio;Accuracy;Precision (Positive);Recall (Positive);Precision (Negative);Recall (Negative);Classify evaluation set (sec);Duration (sec)" << endl;
    }
    string cutOffRatio = "1:1";
    if(_cutOff == 3) {
        cutOffRatio = "2:1";
    }
    else if(_cutOff == 4) {
        cutOffRatio = "3:1";
    }
    //output << benchmarkNr << ";" << getClassifier() << ";" << getTransformer() << ";" << getFeatureSelector() << ";" << cutOffRatio << ";" << clOutput->accuracy << ";" << clOutput->posPrecision << ";" << clOutput->posRecall << ";" << clOutput->negPrecision << ";" << clOutput->negRecall << ";" << (_end - _begin) << endl;
    output << benchmarkNr << ";" << getClassifier() << ";" << getTransformer() << ";" << getFeatureSelector() << ";" << cutOffRatio << ";" << clOutput->accuracy << ";" << clOutput->posPrecision << ";" << clOutput->posRecall << ";" << clOutput->negPrecision << ";" << clOutput->negRecall << ";" << clOutput->traininngTime << ";" << clOutput->getDuration() << endl;
    output.close();
    pthread_mutex_unlock(&csv_mutex);
}
shared_ptr<BehaviorExecution> InstanceSpecification::executeOperation(const string& name,OperationCallParameters&p)
{
	shared_ptr<BehaviorExecution> be;
	//find operation
	try
	{
		shared_ptr<Class> c=getClassifier();
		if (c)
		{
			shared_ptr<Operation> op= MAP_AT(c->getOperations(), name);
			Parameters behaviorParameters;
			if (!op->createBehaviorParameters(p,behaviorParameters))
			{
				cerr<<"Parameters are not correct"<<endl;
				return be;
			}
			//TODO Method!!!
			shared_ptr<Behavior> b= op->getMethod();
			if (b)
			{
				be=BehaviorScheduler::getInstance()->executeBehavior(b,shared_dynamic_cast<InstanceSpecification>(shared_from_this()),behaviorParameters);
				//bind(&Personnel_parler::onUtter, this,_1);
				be->addCallbackOnBehaviorStop(boost::bind( &InstanceSpecification::onBehaviorStopped, this,_1));
			}
		}
	}
	catch(std::out_of_range&)
	{
		// TODO: Error catching
	}
	if(be)
	{
		fireExecuteOperation(be);
		_operationsExecution.push_back(be);
	}
	return be;
}