//
// $Id: OvalEnum.cpp,v 1.15 2007/01/09 17:43:01 bakerj Exp $
//
//****************************************************************************************//
// Copyright (c) 2002-2007, The MITRE Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice, this list
//       of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice, this 
//       list of conditions and the following disclaimer in the documentation and/or other
//       materials provided with the distribution.
//     * Neither the name of The MITRE Corporation nor the names of its contributors may be
//       used to endorse or promote products derived from this software without specific 
//       prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
// SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
// TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//****************************************************************************************//

#include "OvalEnum.h"


//****************************************************************************************//
//									OvalEnum Class										  //	
//****************************************************************************************//
string OvalEnum::CheckToString(OvalEnum::Check check) {
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Convert the check value to a string
	// -----------------------------------------------------------------------

	string checkStr = "";

	switch(check) {
		case (ALL_CHECK):
			checkStr = "all";
			break;
		case (AT_LEAST_ONE_CHECK):
			checkStr = "at least one";
			break;
		case (NONE_EXIST_CHECK):
			checkStr = "none exist";
			break;
		case (ONLY_ONE_CHECK):
			checkStr = "only one";
			break;
		default:	
			throw Exception("OvalEnum::CheckToString - Error unsupported check value.");
			break;
	}

	return checkStr;
}

OvalEnum::Check OvalEnum::ToCheck(string checkStr) {
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Convert the string to a Check
	//
	// -----------------------------------------------------------------------

	OvalEnum::Check check;
	
	if(checkStr.compare(OvalEnum::CheckToString(ALL_CHECK)) == 0 || checkStr.compare("") == 0) {
		check = ALL_CHECK;
	} else if(checkStr.compare(OvalEnum::CheckToString(AT_LEAST_ONE_CHECK)) == 0) {
		check = AT_LEAST_ONE_CHECK;
	} else if(checkStr.compare(OvalEnum::CheckToString(NONE_EXIST_CHECK)) == 0) {
		check = NONE_EXIST_CHECK;
	} else if(checkStr.compare(OvalEnum::CheckToString(ONLY_ONE_CHECK)) == 0) {
		check = ONLY_ONE_CHECK;
	} else {
		throw Exception("OvalEnum::ToCheck - Error unsupported check value: " + checkStr);
	}

	return check;
}

string OvalEnum::DatatypeToString(OvalEnum::Datatype datatype){
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Conver the Datatype value to a string
	// -----------------------------------------------------------------------

	string datatypeStr = "";

	switch(datatype) {
		case (STRING_TYPE):
			datatypeStr = "string";
			break;
		case (INTEGER_TYPE):
			datatypeStr = "int";
			break;
		case (IOS_VERSION_TYPE):
			datatypeStr = "ios_version";
			break;			
		case (BINARY_TYPE):
			datatypeStr = "binary";
			break;
		case (BOOLEAN_TYPE):
			datatypeStr = "boolean";
			break;
		case (EVR_STRING_TYPE):
			datatypeStr = "evr_string";
			break;
		case (FLOAT_TYPE):
			datatypeStr = "float";
			break;
		case (VERSION_TYPE):
			datatypeStr = "version";
			break;
		default:	
			throw Exception("OvalEnum::DatatypeToString - Error unsupported datatype.");
			break;
	}

	return datatypeStr;
}

OvalEnum::Datatype OvalEnum::ToDatatype(string datatypeStr){
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Convert the string to a Datatype
	//
	// -----------------------------------------------------------------------

	OvalEnum::Datatype datatype;
	
	if(datatypeStr.compare(OvalEnum::DatatypeToString(STRING_TYPE)) == 0 || datatypeStr.compare("") == 0) {
		datatype = STRING_TYPE;
	} else if(datatypeStr.compare(OvalEnum::DatatypeToString(INTEGER_TYPE)) == 0) {
		datatype = INTEGER_TYPE;
	} else if(datatypeStr.compare(OvalEnum::DatatypeToString(IOS_VERSION_TYPE)) == 0) {
		datatype = IOS_VERSION_TYPE;
	} else if(datatypeStr.compare(OvalEnum::DatatypeToString(BINARY_TYPE)) == 0) {
		datatype = BINARY_TYPE;
	} else if(datatypeStr.compare(OvalEnum::DatatypeToString(BOOLEAN_TYPE)) == 0) {
		datatype = BOOLEAN_TYPE;
	} else if(datatypeStr.compare(OvalEnum::DatatypeToString(EVR_STRING_TYPE)) == 0) {
		datatype = EVR_STRING_TYPE;
	} else if(datatypeStr.compare(OvalEnum::DatatypeToString(FLOAT_TYPE)) == 0) {
		datatype = FLOAT_TYPE;
	} else if(datatypeStr.compare(OvalEnum::DatatypeToString(VERSION_TYPE)) == 0) {
		datatype = VERSION_TYPE;
	} else {
		throw Exception("OvalEnum::ToDatatype - Error unsupported datatype value: " + datatypeStr);
	}

	return datatype;
}

string OvalEnum::FlagToString(OvalEnum::Flag flag) {
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Convert the Flag value to a string
	//
	// -----------------------------------------------------------------------
	string flagStr = "";

	switch(flag) {
		case (ERROR_FLAG):
			flagStr = "error";
			break;
		case (COMPLETE_FLAG):
			flagStr = "complete";
			break;
		case (INCOMPLETE_FLAG):
			flagStr = "incomplete";
			break;
		case (DOES_NOT_EXIST_FLAG):
			flagStr = "does not exist";
			break;
		case (NOT_COLLECTED_FLAG):
			flagStr = "not collected";
			break;
		case (NOT_APPLICABLE_FLAG):
			flagStr = "not applicable";
			break;
		default:
			throw Exception("OvalEnum::FlagToString - Error unsupported flag value.");
			break;
	}
	return flagStr;
}

OvalEnum::Flag OvalEnum::ToFlag(string flagStr){
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Convert the string to a CollectedObjectFlag value
	// -----------------------------------------------------------------------

	OvalEnum::Flag flag;
	
	if(flagStr.compare(OvalEnum::FlagToString(COMPLETE_FLAG)) == 0 || flagStr.compare("") == 0) {
		flag = COMPLETE_FLAG;
	} else if(flagStr.compare(OvalEnum::FlagToString(ERROR_FLAG)) == 0) {
		flag = ERROR_FLAG;
	} else if(flagStr.compare(OvalEnum::FlagToString(INCOMPLETE_FLAG)) == 0) {
		flag = INCOMPLETE_FLAG;
	} else if(flagStr.compare(OvalEnum::FlagToString(DOES_NOT_EXIST_FLAG)) == 0) {
		flag = DOES_NOT_EXIST_FLAG;
	} else if(flagStr.compare(OvalEnum::FlagToString(NOT_COLLECTED_FLAG)) == 0) {
		flag = NOT_COLLECTED_FLAG;
	} else if(flagStr.compare(OvalEnum::FlagToString(NOT_APPLICABLE_FLAG)) == 0) {
		flag = NOT_APPLICABLE_FLAG;
	} else {
		throw Exception("OvalEnum::ToFlag - Error unsupported flag value: " + flagStr);
	}

	return flag;
}

OvalEnum::Flag OvalEnum::CombineFlags(IntVector* flags) {
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Combine the set of flag values to a single flag value.
	// -----------------------------------------------------------------------

	OvalEnum::Flag combinedFlag = OvalEnum::ERROR_FLAG;

	// Make sure the flags vector has items. Return error flag if it is empty
	if(flags->size() == 0) {
		return combinedFlag;
	}

	// Get counts of flag values
	int errorCount = 0;
	int completeCount = 0;
	int incompleteCount = 0;
	int doesNotExistCount = 0;
	int notCollectedCount = 0;
	int notApplicableCount = 0;
	IntVector::iterator flag;
	for (flag=flags->begin(); flag!=flags->end(); flag++) {

		if((*flag) == OvalEnum::ERROR_FLAG) {
			errorCount++;
		} else if((*flag) == OvalEnum::COMPLETE_FLAG) {
			completeCount++;
		} else if((*flag) == OvalEnum::INCOMPLETE_FLAG) {
			incompleteCount++;
		} else if((*flag) == OvalEnum::DOES_NOT_EXIST_FLAG) {
			doesNotExistCount++;
		} else if((*flag) == OvalEnum::NOT_COLLECTED_FLAG) {
			notCollectedCount++;
		} else if((*flag) == OvalEnum::NOT_APPLICABLE_FLAG) {
			notApplicableCount++;
		} 
	}

	if(errorCount > 0) {
		combinedFlag = OvalEnum::ERROR_FLAG;
	} else if(errorCount == 0 
		&& completeCount > 0 
		&& incompleteCount == 0 
		&& doesNotExistCount == 0 
		&& notCollectedCount == 0 
		&& notApplicableCount == 0) {

		combinedFlag = OvalEnum::COMPLETE_FLAG;

	} else if(errorCount == 0 
		&& completeCount > 0 
		&& incompleteCount == 0 
		&& doesNotExistCount == 0 
		&& notCollectedCount == 0 
		&& notApplicableCount == 0) {

		combinedFlag = OvalEnum::INCOMPLETE_FLAG;

	} else if(errorCount == 0 
		&& completeCount >= 0 
		&&  incompleteCount >= 0 
		&& doesNotExistCount > 0 
		&& notCollectedCount == 0 
		&& notApplicableCount == 0) {

		combinedFlag = OvalEnum::DOES_NOT_EXIST_FLAG;

	} else if(errorCount == 0 
		&& completeCount >= 0 
		&&  incompleteCount >= 0 
		&& doesNotExistCount >= 0 
		&& notCollectedCount > 0 
		&& notApplicableCount == 0) {

		combinedFlag = OvalEnum::NOT_COLLECTED_FLAG;

	} else if(errorCount == 0 
		&& completeCount >= 0 
		&&  incompleteCount >= 0 
		&& doesNotExistCount >= 0 
		&& notCollectedCount >= 0 
		&& notApplicableCount > 0) {

		combinedFlag = OvalEnum::NOT_APPLICABLE_FLAG;

	}	

	return combinedFlag;
}

string OvalEnum::LevelToString(OvalEnum::Level level){
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Convert the Level value to a string
	// -----------------------------------------------------------------------

	string levelStr = "";

	switch(level) {
		case (DEBUG_LEVEL):
			levelStr = "debug";
			break;
		case (ERROR_LEVEL):
			levelStr = "error";
			break;
		case (FATAL_LEVEL):
			levelStr = "fatal";
			break;
		case (INFO_LEVEL):
			levelStr = "info";
			break;
		case (WARNING_LEVEL):
			levelStr = "warning";
			break;
		default:	
			throw Exception("OvalEnum::LevelToString - Error unsupported level.");
			break;
	};

	return levelStr;
}

OvalEnum::Level OvalEnum::ToLevel(string levelStr){
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Convert the string to a Datatype
	//
	// -----------------------------------------------------------------------

	Level level;
	
	if(levelStr.compare(OvalEnum::LevelToString(INFO_LEVEL)) == 0 || levelStr.compare("") == 0) {
		level = INFO_LEVEL;
	} else if(levelStr.compare(OvalEnum::LevelToString(DEBUG_LEVEL)) == 0) {
		level = DEBUG_LEVEL;
	} else if(levelStr.compare(OvalEnum::LevelToString(ERROR_LEVEL)) == 0) {
		level = ERROR_LEVEL;
	} else if(levelStr.compare(OvalEnum::LevelToString(FATAL_LEVEL)) == 0) {
		level = FATAL_LEVEL;
	} else if(levelStr.compare(OvalEnum::LevelToString(WARNING_LEVEL)) == 0) {
		level = WARNING_LEVEL;
	} else {
		throw Exception("OvalEnum::Tolevel - Error unsupported level value: " + levelStr);
	}

	return level;
}

string OvalEnum::OperationToString(OvalEnum::Operation operation){
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Convert the Operation value to a string
	//
	// -----------------------------------------------------------------------
	string operationStr = "";

	switch(operation) {
		case (EQUALS_OPERATION):
			operationStr = "equals";
			break;
		case (NOT_EQUAL_OPERATION):
			operationStr = "not equal";
			break;
		case (GREATER_THAN_OPERATION):
			operationStr = "greater than";
			break;
		case (LESS_THAN_OPERATION):
			operationStr = "less than";
			break;
		case (GREATER_THAN_OR_EQUAL_OPERATION):
			operationStr = "greater than or equal";
			break;
		case (LESS_THAN_OR_EQUAL_OPERATION):
			operationStr = "less than or equal";
			break;
		case (BITWISE_AND_OPERATION):
			operationStr = "bitwise and";
			break;
		case (BITWISE_OR_OPERATION):
			operationStr = "bitwise or";
			break;
		case (PATTERN_MATCH_OPERATION):
			operationStr = "pattern match";
			break;
		default:
			throw Exception("OvalEnum::OperationToString - Error unsupported operation value.");
			break;
	}
	return operationStr;
}

OvalEnum::Operation OvalEnum::ToOperation(string operationStr){
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Convert the string to a Operation value
	// -----------------------------------------------------------------------

	OvalEnum::Operation operation;
	
	if(operationStr.compare(OvalEnum::OperationToString(EQUALS_OPERATION)) == 0 || operationStr.compare("") == 0) {
		operation = EQUALS_OPERATION;
	} else if(operationStr.compare(OvalEnum::OperationToString(NOT_EQUAL_OPERATION)) == 0) {
		operation = NOT_EQUAL_OPERATION;
	} else if(operationStr.compare(OvalEnum::OperationToString(GREATER_THAN_OPERATION)) == 0) {
		operation = GREATER_THAN_OPERATION;
	} else if(operationStr.compare(OvalEnum::OperationToString(LESS_THAN_OPERATION)) == 0) {
		operation = LESS_THAN_OPERATION;
	} else if(operationStr.compare(OvalEnum::OperationToString(GREATER_THAN_OR_EQUAL_OPERATION)) == 0) {
		operation = GREATER_THAN_OR_EQUAL_OPERATION;
	} else if(operationStr.compare(OvalEnum::OperationToString(LESS_THAN_OR_EQUAL_OPERATION)) == 0) {
		operation = LESS_THAN_OR_EQUAL_OPERATION;
	} else if(operationStr.compare(OvalEnum::OperationToString(BITWISE_AND_OPERATION)) == 0) {
		operation = BITWISE_AND_OPERATION;
	} else if(operationStr.compare(OvalEnum::OperationToString(BITWISE_OR_OPERATION)) == 0) {
		operation = BITWISE_OR_OPERATION;
	} else if(operationStr.compare(OvalEnum::OperationToString(PATTERN_MATCH_OPERATION)) == 0) {
		operation = PATTERN_MATCH_OPERATION;
	} else {
		throw Exception("OvalEnum::ToOperation - Error unsupported operation value: " + operationStr);
	}

	return operation;
}

OvalEnum::Operator OvalEnum::ToOperator(string operatorStr) {
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Convert the string to an Operator
	//
	// -----------------------------------------------------------------------

	OvalEnum::Operator op;
	
	if(operatorStr.compare(OvalEnum::OperatorToString(AND_OPERATOR)) == 0 || operatorStr.compare("") == 0) {
		op = AND_OPERATOR;
	} else if(operatorStr.compare(OvalEnum::OperatorToString(OR_OPERATOR)) == 0) {
		op = OR_OPERATOR;
	} else if(operatorStr.compare(OvalEnum::OperatorToString(XOR_OPERATOR)) == 0) {
		op = XOR_OPERATOR;
	} else {
		throw Exception("OvalEnum::ToOperator - Error unsupported operator value: " + operatorStr);
	}

	return op;	
}

string OvalEnum::OperatorToString(OvalEnum::Operator op) {
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	convert the Operator to a string
	//
	// -----------------------------------------------------------------------
	string operatorStr = "";

	switch(op) {
		case (AND_OPERATOR):
			operatorStr = "AND";
			break;
		case (OR_OPERATOR):
			operatorStr = "OR";
			break;
		case (XOR_OPERATOR):
			operatorStr = "XOR";
			break;
		default:
			throw Exception("OvalEnum::OperationToString - Error unsupported operator value.");
			break;
	}
	return operatorStr;
}

OvalEnum::ResultEnumeration OvalEnum::ToResult(string resultStr) {
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Convert the string to an Result
	//
	// -----------------------------------------------------------------------

	OvalEnum::ResultEnumeration result;
	
	if(resultStr.compare(OvalEnum::ResultToString(TRUE_RESULT)) == 0) {
		result = TRUE_RESULT;
	} else if(resultStr.compare(OvalEnum::ResultToString(FALSE_RESULT)) == 0) {
		result = FALSE_RESULT;
	} else if(resultStr.compare(OvalEnum::ResultToString(UNKNOWN_RESULT)) == 0) {
		result = UNKNOWN_RESULT;
	} else if(resultStr.compare(OvalEnum::ResultToString(ERROR_RESULT)) == 0) {
		result = ERROR_RESULT;
	} else if(resultStr.compare(OvalEnum::ResultToString(NOT_EVALUATED_RESULT)) == 0) {
		result = NOT_EVALUATED_RESULT;
	} else if(resultStr.compare(OvalEnum::ResultToString(NOT_APPLICABLE_RESULT)) == 0) {
		result = NOT_APPLICABLE_RESULT;
	} else {
		throw Exception("OvalEnum::ToOperator - Error unsupported result value: " + resultStr);
	}

	return result;	
}

string OvalEnum::ResultToString(OvalEnum::ResultEnumeration result) {
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	convert the ResultEnumeration to a string
	//
	// -----------------------------------------------------------------------
	string resultStr = "";

	switch(result) {
		case (TRUE_RESULT):
			resultStr = "true";
			break;
		case (FALSE_RESULT):
			resultStr = "false";
			break;
		case (UNKNOWN_RESULT):
			resultStr = "unknown";
			break;
		case (ERROR_RESULT):
			resultStr = "error";
			break;
		case (NOT_EVALUATED_RESULT):
			resultStr = "not evaluated";
			break;
		case (NOT_APPLICABLE_RESULT):
			resultStr = "not applicable";
			break;
		default:
			throw Exception("OvalEnum::ResultEnumeration - Error unsupported result value.");
			break;
	}
	return resultStr;
}

OvalEnum::ResultEnumeration OvalEnum::CombineResultsByCheck(IntVector* results, OvalEnum::Check check) {
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Return a result value based on combining the results in the 
	//	provided array and considering the provided check value
	//
	//	This function assigns precidence to the non t/f result values as follows
	//		- 1 - error
	//		- 2 - unknown
	//		- 3 - not evaluated
	// -----------------------------------------------------------------------

	OvalEnum::ResultEnumeration combinedResult = UNKNOWN_RESULT;

	// Make sure the results vector has items. Return unknown_result if it is empty
	if(results->size() == 0) {
		return UNKNOWN_RESULT;
	}

	// Get counts of result values
	int trueCount = 0;
	int falseCount = 0;
	int unknownCount = 0;
	int errorCount = 0;
	int notEvaluatedCount = 0;
	int notApplicableCount = 0;
	IntVector::iterator result;
	for (result=results->begin(); result!=results->end(); result++) {

		if((*result) == OvalEnum::TRUE_RESULT) {
			trueCount++;
		} else if((*result) == OvalEnum::FALSE_RESULT) {
			falseCount++;
		} else if((*result) == OvalEnum::UNKNOWN_RESULT) {
			unknownCount++;
		} else if((*result) == OvalEnum::ERROR_RESULT) {
			errorCount++;
		} else if((*result) == OvalEnum::NOT_EVALUATED_RESULT) {
			notEvaluatedCount++;
		} else if((*result) == OvalEnum::NOT_APPLICABLE_RESULT) {
			notApplicableCount++;
		} 
	}

	// first check for a possible Not Applicable result
	if(notApplicableCount > 0 && notEvaluatedCount == 0 && falseCount == 0 && errorCount == 0 && unknownCount == 0 && trueCount == 0) {
		return OvalEnum::NOT_APPLICABLE_RESULT;
	}

	// Set the combined result
	if(check == OvalEnum::ALL_CHECK) {
		if(trueCount > 0 && falseCount == 0 && errorCount == 0 && unknownCount == 0 && notEvaluatedCount == 0) {
			combinedResult = OvalEnum::TRUE_RESULT;
		} else if(falseCount > 0) {
			combinedResult = OvalEnum::FALSE_RESULT;
		} else if(falseCount == 0 && errorCount > 0) {
			combinedResult = OvalEnum::ERROR_RESULT;
		} else if(unknownCount > 0 && falseCount == 0 && errorCount == 0) {
			combinedResult = OvalEnum::UNKNOWN_RESULT;
		} else if(notEvaluatedCount > 0 && falseCount == 0 && errorCount == 0 && unknownCount == 0) {
			combinedResult = OvalEnum::NOT_EVALUATED_RESULT;
		}
	} else if(check == OvalEnum::AT_LEAST_ONE_CHECK) {
		if(trueCount > 0) {
			combinedResult = OvalEnum::TRUE_RESULT;
		} else if(falseCount > 0 && trueCount == 0 && unknownCount == 0 &&  errorCount == 0 &&  notEvaluatedCount == 0) {
			combinedResult = OvalEnum::FALSE_RESULT;
		} else if(errorCount > 0 && trueCount == 0) {
			combinedResult = OvalEnum::ERROR_RESULT;
		} else if(unknownCount > 0 && trueCount == 0 && errorCount == 0) {
			combinedResult = OvalEnum::UNKNOWN_RESULT;
		} else if(notEvaluatedCount > 0 && unknownCount == 0 && trueCount == 0 && errorCount == 0) {
			combinedResult = OvalEnum::NOT_EVALUATED_RESULT;
		}
	} else if(check == OvalEnum::NONE_EXIST_CHECK) {
		if(trueCount > 0) {
			combinedResult = OvalEnum::FALSE_RESULT;
		} else if(errorCount > 0 && trueCount == 0) {	
			combinedResult = OvalEnum::ERROR_RESULT;
		} else if(unknownCount > 0 && errorCount == 0 && trueCount == 0) {	
			combinedResult = OvalEnum::UNKNOWN_RESULT;
		} else if(notEvaluatedCount > 0 && unknownCount == 0 && errorCount == 0 && trueCount == 0) {	
			combinedResult = OvalEnum::NOT_EVALUATED_RESULT;
		} else if(falseCount > 0 && notEvaluatedCount == 0 && unknownCount == 0 && errorCount == 0 && trueCount == 0) {	
			combinedResult = OvalEnum::TRUE_RESULT;
		}
	} else if(check == OvalEnum::ONLY_ONE_CHECK) {
		if(trueCount == 1 && unknownCount == 0 && errorCount == 0 && notEvaluatedCount == 0) {
			combinedResult = OvalEnum::TRUE_RESULT;
		} else if(trueCount > 1) {
			combinedResult = OvalEnum::FALSE_RESULT;
		} else if(errorCount > 0 && trueCount < 2) {
			combinedResult = OvalEnum::ERROR_RESULT;
		} else if(unknownCount > 0 && errorCount == 0 && trueCount < 2) {
			combinedResult = OvalEnum::UNKNOWN_RESULT;
		} else if(notEvaluatedCount > 0 && unknownCount == 0 && errorCount == 0 && trueCount < 2) {
			combinedResult = OvalEnum::NOT_EVALUATED_RESULT;
		} else if(falseCount > 0 && trueCount != 1) {
            combinedResult = OvalEnum::FALSE_RESULT;
		}
	}

	return combinedResult;
}

OvalEnum::ResultEnumeration OvalEnum::CombineResultsByOperator(IntVector* results, OvalEnum::Operator op) {
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Return a result value based on combining the results in the 
	//	provided array and considering the provided operation value
	//
	//	This function assigns precidence to the non t/f result values as follows
	//		- 1 - error
	//		- 2 - unknown
	//		- 3 - not evaluated
	// -----------------------------------------------------------------------

	OvalEnum::ResultEnumeration combinedResult = UNKNOWN_RESULT;

	// Make sure the results vector has items. Return unknown_result if it is empty
	if(results->size() == 0) {
		return UNKNOWN_RESULT;
	}

	// Get counts of result values
	int trueCount = 0;
	int falseCount = 0;
	int unknownCount = 0;
	int errorCount = 0;
	int notEvaluatedCount = 0;
	int notApplicableCount = 0;
	IntVector::iterator result;
	for (result=results->begin(); result!=results->end(); result++) {

		if((*result) == OvalEnum::TRUE_RESULT) {
			trueCount++;
		} else if((*result) == OvalEnum::FALSE_RESULT) {
			falseCount++;
		} else if((*result) == OvalEnum::UNKNOWN_RESULT) {
			unknownCount++;
		} else if((*result) == OvalEnum::ERROR_RESULT) {
			errorCount++;
		} else if((*result) == OvalEnum::NOT_EVALUATED_RESULT) {
			notEvaluatedCount++;
		} else if((*result) == OvalEnum::NOT_APPLICABLE_RESULT) {
			notApplicableCount++;
		} 
	}

	// first check for a possible Not Applicable result
	if(notApplicableCount > 0 && notEvaluatedCount == 0 && falseCount == 0 && errorCount == 0 && unknownCount == 0 && trueCount == 0) {
		return OvalEnum::NOT_APPLICABLE_RESULT;
	}

	// Set the combined result
	if(op == OvalEnum::AND_OPERATOR) {
		if(trueCount > 0 && falseCount == 0 && errorCount == 0 && unknownCount == 0 && notEvaluatedCount == 0) {
			combinedResult = OvalEnum::TRUE_RESULT;
		} else if(falseCount > 0) {
			combinedResult = OvalEnum::FALSE_RESULT;
		} else if(falseCount == 0 && errorCount > 0) {
			combinedResult = OvalEnum::ERROR_RESULT;
		} else if(unknownCount > 0 && falseCount == 0 && errorCount == 0) {
			combinedResult = OvalEnum::UNKNOWN_RESULT;
		} else if(notEvaluatedCount > 0 && falseCount == 0 && errorCount == 0 && unknownCount == 0) {
			combinedResult = OvalEnum::NOT_EVALUATED_RESULT;
		}
	} else if(op == OvalEnum::OR_OPERATOR) {
		if(trueCount > 0) {
			combinedResult = OvalEnum::TRUE_RESULT;
		} else if(falseCount > 0 && trueCount == 0 && unknownCount == 0 &&  errorCount == 0 &&  notEvaluatedCount == 0) {
			combinedResult = OvalEnum::FALSE_RESULT;
		} else if(errorCount > 0 && trueCount == 0) {
			combinedResult = OvalEnum::ERROR_RESULT;
		} else if(unknownCount > 0 && trueCount == 0 && errorCount == 0) {
			combinedResult = OvalEnum::UNKNOWN_RESULT;
		} else if(notEvaluatedCount > 0 && unknownCount == 0 && trueCount == 0 && errorCount == 0) {
			combinedResult = OvalEnum::NOT_EVALUATED_RESULT;
		}
	} else if(op == OvalEnum::XOR_OPERATOR) {
		if(trueCount%2 == 1 && notEvaluatedCount == 0 && unknownCount == 0 && errorCount == 0) {
			combinedResult = OvalEnum::TRUE_RESULT;
		} else if(trueCount%2 == 0 && notEvaluatedCount == 0 && unknownCount == 0 && errorCount == 0) {	
			combinedResult = OvalEnum::FALSE_RESULT;
		} else if(errorCount > 0) {	
			combinedResult = OvalEnum::ERROR_RESULT;
		} else if(unknownCount > 0 && errorCount == 0) {	
			combinedResult = OvalEnum::UNKNOWN_RESULT;
		} else if(notEvaluatedCount > 0 && unknownCount == 0 && errorCount == 00) {	
			combinedResult = OvalEnum::NOT_EVALUATED_RESULT;
		}
	}

	return combinedResult;
}

OvalEnum::ResultEnumeration OvalEnum::NegateResult(OvalEnum::ResultEnumeration result) {
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	negate the result value and return it
	//
	// -----------------------------------------------------------------------

	if(result == OvalEnum::TRUE_RESULT) {
		return OvalEnum::FALSE_RESULT;
	} else if(result == OvalEnum::FALSE_RESULT) {
			return OvalEnum::TRUE_RESULT;
	} else {
		return result;
	}

}

string OvalEnum::SCStatusToString(OvalEnum::SCStatus status){
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Convert the SCStatus value to a string
	//
	// -----------------------------------------------------------------------
	string statusStr = "";

	switch(status) {
		case (OvalEnum::DOES_NOT_EXIST_STATUS):
			statusStr = "does not exist";
			break;
		case (OvalEnum::ERROR_STATUS):
			statusStr = "error";
			break;
		case (OvalEnum::EXISTS_STATUS):
			statusStr = "exists";
			break;
		case (OvalEnum::NOT_COLLECTED_STATUS):
			statusStr = "not collected";
			break;
	}
	return statusStr;
}

OvalEnum::SCStatus OvalEnum::ToSCStatus(string statusStr){
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Convert the string to a SCStatus value
	// -----------------------------------------------------------------------

	OvalEnum::SCStatus scStatus = OvalEnum::ERROR_STATUS;
	
	if(statusStr.compare(OvalEnum::SCStatusToString(OvalEnum::DOES_NOT_EXIST_STATUS)) == 0) {
		scStatus = OvalEnum::DOES_NOT_EXIST_STATUS;
	} else if(statusStr.compare(OvalEnum::SCStatusToString(OvalEnum::ERROR_STATUS)) == 0) {
		scStatus = OvalEnum::ERROR_STATUS;
	} else if(statusStr.compare(OvalEnum::SCStatusToString(OvalEnum::EXISTS_STATUS)) == 0 || statusStr.compare("") == 0) {
		scStatus = OvalEnum::EXISTS_STATUS;
	} else if(statusStr.compare(OvalEnum::SCStatusToString(OvalEnum::NOT_COLLECTED_STATUS)) == 0) {
		scStatus = OvalEnum::NOT_COLLECTED_STATUS;
	}

	return scStatus;
}

string OvalEnum::SetOperatorToString(OvalEnum::SetOperator setOperator){
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Convert the SetOperator value to a string
	//
	// -----------------------------------------------------------------------
	string setOperatorStr = "";

	switch(setOperator) {
		case (OvalEnum::COMPLEMENT_SET_OPERATOR):
			setOperatorStr = "COMPLEMENT";
			break;
		case (OvalEnum::INTERSECTION_SET_OPERATOR):
			setOperatorStr = "INTERSECTION";
			break;
		case (OvalEnum::UNION_SET_OPERATOR):
			setOperatorStr = "UNION";
			break;
		default:
			throw Exception("Set::SetOperatorToString - Error unsupported setOperator value.");
			break;
	}
	return setOperatorStr;
}

OvalEnum::SetOperator OvalEnum::ToSetOperator(string setOperatorStr){
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Convert the string to a SetOperator value
	// -----------------------------------------------------------------------

	SetOperator setOperator;
	
	if(setOperatorStr.compare(OvalEnum::SetOperatorToString(UNION_SET_OPERATOR)) == 0 || setOperatorStr.compare("") == 0) {
		setOperator = OvalEnum::UNION_SET_OPERATOR;
	} else if(setOperatorStr.compare(OvalEnum::SetOperatorToString(COMPLEMENT_SET_OPERATOR)) == 0) {
		setOperator = OvalEnum::COMPLEMENT_SET_OPERATOR;
	} else if(setOperatorStr.compare(OvalEnum::SetOperatorToString(INTERSECTION_SET_OPERATOR)) == 0) {
		setOperator = OvalEnum::INTERSECTION_SET_OPERATOR;
	} else {
		throw Exception("OvalEnum::ToSetOperator - Error unsupported setOperator value: " + setOperatorStr);
	}

	return setOperator;
}
