//--
	bool DataProperty::Satisfy(OpenBabel::OBBond* pBond, 
								const std::string& refTo, 
								std::vector<Class*>& vecSatisfiedClasses, 
								std::string& refValue)
	{
		//bool bSatisfied = false;
		int iPosition = -1;

		// [rad] if we are default, we automatically satisfy		
		if(!IsDefault())
		{			
			if(!SatisfyCommon(vecSatisfiedClasses, iPosition))
			{
				// [rad] this property does not apply

				refValue = "";
				return(false);
			}
		}

		// [rad] go through possible data types..

		if(!refTo.compare("BOND_ORDER"))
		{
			ConvertInt(pBond->GetBondOrder(), refValue);
		}
		else if(!refTo.compare("BOND_EQUILIBRIUM_LENGTH"))
		{
			ConvertDouble(pBond->GetEquibLength(), refValue);
		}
		else if(!refTo.compare("BOND_LENGTH"))
		{
			ConvertDouble(pBond->GetLength(), refValue);
		}
		else if(!refTo.compare("BOND_IS_AROMATIC"))
		{
			ConvertBool(pBond->IsAromatic(), refValue);
		}
		else if(!refTo.compare("BOND_IS_IN_RING"))
		{
			ConvertBool(pBond->IsInRing(), refValue);
		}
		else if(!refTo.compare("BOND_IS_ROTOR"))
		{
			ConvertBool(pBond->IsRotor(), refValue);
		}
		else if(!refTo.compare("BOND_IS_AMIDE"))
		{
			ConvertBool(pBond->IsAmide(), refValue);
		}
		else if(!refTo.compare("BOND_IS_PRIMARY_AMIDE"))
		{
			ConvertBool(pBond->IsPrimaryAmide(), refValue);
		}
		else if(!refTo.compare("BOND_IS_SECONDARY_AMIDE"))
		{
			ConvertBool(pBond->IsSecondaryAmide(), refValue);
		}
		else if(!refTo.compare("BOND_IS_ESTER"))
		{
			ConvertBool(pBond->IsEster(), refValue);
		}
		else if(!refTo.compare("BOND_IS_CARBONYL"))
		{
			ConvertBool(pBond->IsCarbonyl(), refValue);
		}
		else if(!refTo.compare("BOND_IS_SINGLE_BOND"))
		{
			ConvertBool(pBond->IsSingle(), refValue);
		}
		else if(!refTo.compare("BOND_IS_DOUBLE_BOND"))
		{
			ConvertBool(pBond->IsDouble(), refValue);
		}
		else if(!refTo.compare("BOND_IS_TRIPLE_BOND"))
		{
			ConvertBool(pBond->IsTriple(), refValue);
		}
		else if(!refTo.compare("BOND_IS_CLOSURE_BOND"))
		{
			ConvertBool(pBond->IsClosure(), refValue);
		}
		else if(!refTo.compare("BOND_IS_UP"))
		{
			ConvertBool(pBond->IsUp(), refValue);
		}
		else if(!refTo.compare("BOND_IS_DOWN"))
		{
			ConvertBool(pBond->IsDown(), refValue);
		}
		else if(!refTo.compare("BOND_IS_HASH"))
		{
			ConvertBool(pBond->IsHash(), refValue);
		}
		else if(!refTo.compare("BOND_IS_WEDGE"))
		{
			ConvertBool(pBond->IsWedge(), refValue);
		}
		else
		{
			// [rad] unknown datatype?
			refValue = "";
			return(false);
		}

		return(true);
	}
	//--
	bool DataProperty::Satisfy(OpenBabel::OBAtom* pAtom, 
								const std::string& refTo, 
								std::vector<Class*>& vecSatisfiedClasses, 
								std::string& refValue)
	{
		//bool bSatisfied = false;
		int iPosition = -1;

		// [rad] if we are default, we automatically satisfy		
		if(!IsDefault())
		{			
			if(!SatisfyCommon(vecSatisfiedClasses, iPosition))
			{
				// [rad] this property does not apply

				refValue = "";
				return(false);
			}
		}

		// [rad] go through possible data types..

		if(!refTo.compare("ATOM_ATOMIC_NUMBER"))
		{
			ConvertInt(pAtom->GetAtomicNum(), refValue);
		}
		else if(!refTo.compare("ATOM_FORMAL_CHARGE"))
		{
			ConvertInt(pAtom->GetFormalCharge(), refValue);
		}
		else if(!refTo.compare("ATOM_ISOTOPE"))
		{
			ConvertInt(pAtom->GetIsotope(), refValue);
		}
		else if(!refTo.compare("ATOM_SPIN_MULTIPLICITY"))
		{
			ConvertInt(pAtom->GetSpinMultiplicity(), refValue);
		}
		else if(!refTo.compare("ATOM_ATOMIC_MASS"))
		{
			ConvertDouble(pAtom->GetAtomicMass(), refValue);
		}
		else if(!refTo.compare("ATOM_EXACT_MASS"))
		{
			ConvertDouble(pAtom->GetExactMass(), refValue);
		}
		else if(!refTo.compare("ATOM_INTERNAL_INDEX"))
		{
			ConvertInt(pAtom->GetIdx(), refValue);
		}
		else if(!refTo.compare("ATOM_VALENCE"))
		{
			ConvertInt(pAtom->GetValence(), refValue);
		}
		else if(!refTo.compare("ATOM_HYBRIDIZATION"))
		{
			ConvertInt(pAtom->GetHyb(), refValue);
		}
		else if(!refTo.compare("ATOM_IMPLICIT_VALENCE"))
		{
			ConvertInt(pAtom->GetImplicitValence(), refValue);
		}
		else if(!refTo.compare("ATOM_HEAVY_VALENCE"))
		{
			ConvertInt(pAtom->GetHvyValence(), refValue);
		}
		else if(!refTo.compare("ATOM_HETERO_VALENCE"))
		{
			ConvertInt(pAtom->GetHeteroValence(), refValue);
		}
		else if(!refTo.compare("ATOM_COORDINATE_X"))
		{
			ConvertDouble(pAtom->GetX(), refValue);
		}
		else if(!refTo.compare("ATOM_COORDINATE_Y"))
		{
			ConvertDouble(pAtom->GetY(), refValue);
		}
		else if(!refTo.compare("ATOM_COORDINATE_Z"))
		{
			ConvertDouble(pAtom->GetZ(), refValue);
		}
		else if(!refTo.compare("ATOM_PARTIAL_CHARGE"))
		{
			ConvertDouble(pAtom->GetPartialCharge(), refValue);
		}
		else if(!refTo.compare("ATOM_FREE_OXYGEN_COUNT"))
		{
			ConvertInt(pAtom->CountFreeOxygens(), refValue);
		}
		else if(!refTo.compare("ATOM_IMPLICIT_HYDROGEN_COUNT"))
		{
			ConvertInt(pAtom->ImplicitHydrogenCount(), refValue);
		}
		else if(!refTo.compare("ATOM_PARTICIPANT_RING_COUNT"))
		{
			ConvertInt(pAtom->MemberOfRingCount(), refValue);
		}
		else if(!refTo.compare("ATOM_AVERAGE_BOND_ANGLE"))
		{
			ConvertDouble(pAtom->AverageBondAngle(), refValue);
		}
		else if(!refTo.compare("ATOM_SMALLEST_BOND_ANGLE"))
		{
			ConvertDouble(pAtom->SmallestBondAngle(), refValue);
		}
		else if(!refTo.compare("ATOM_IS_IN_RING"))
		{
			ConvertBool(pAtom->IsInRing(), refValue);
		}
		else if(!refTo.compare("ATOM_IS_HETERO_ATOM"))
		{
			ConvertBool(pAtom->IsHeteroatom(), refValue);
		}
		else if(!refTo.compare("ATOM_IS_AROMATIC"))
		{
			ConvertBool(pAtom->IsAromatic(), refValue);
		}
		else if(!refTo.compare("ATOM_IS_CHIRAL"))
		{
			ConvertBool(pAtom->IsChiral(), refValue);
		}
		else if(!refTo.compare("ATOM_HAS_SINGLE_BOND"))
		{
			ConvertBool(pAtom->HasSingleBond(), refValue);
		}
		else if(!refTo.compare("ATOM_HAS_DOUBLE_BOND"))
		{
			ConvertBool(pAtom->HasDoubleBond(), refValue);
		}
		else if(!refTo.compare("ATOM_HAS_TRIPLE_BOND"))
		{
			ConvertBool(pAtom->HasBondOfOrder(3), refValue);
		}		
		else if(!refTo.compare("ATOM_HAS_AROMATIC_BOND"))
		{
			ConvertBool(pAtom->HasAromaticBond(), refValue);
		}		
		else if(!refTo.compare("ATOM_SINGLE_BOND_COUNT"))
		{
			ConvertInt(pAtom->CountBondsOfOrder(1), refValue);
		}
		else if(!refTo.compare("ATOM_DOUBLE_BOND_COUNT"))
		{
			ConvertInt(pAtom->CountBondsOfOrder(2), refValue);
		}
		else if(!refTo.compare("ATOM_TRIPLE_BOND_COUNT"))
		{
			ConvertInt(pAtom->CountBondsOfOrder(3), refValue);
		}
		else if(!refTo.compare("ATOM_AROMATIC_BOND_COUNT"))
		{
			ConvertInt(pAtom->CountBondsOfOrder(5), refValue);
		}
		else if(!refTo.compare("ATOM_BOND_COUNT"))
		{
			//return(ConvertInt(pAtom->CountBondsOfOrder(5)));
			OpenBabel::OBBond* pBond;
			std::vector<OpenBabel::OBEdgeBase*>::iterator iter_bond;
			int iCount = 0;

			for(pBond = pAtom->BeginBond(iter_bond); pBond; pBond = pAtom->NextBond(iter_bond))
			{
				iCount++;
			}
	
			ConvertInt(iCount, refValue);
		}
		else
		{
			// [rad] unknown datatype?
			refValue = "";
			return(false);
		}

		return(true);
	}
	//--
	bool DataProperty::Satisfy(OpenBabel::OBRing* pRing, 
								const std::string& refTo, 
								std::vector<Class*>& vecSatisfiedClasses, 
								std::string& refValue)
	{
		//bool bSatisfied = false;
		int iPosition = -1;

		// [rad] if we are default, we automatically satisfy		
		if(!IsDefault())
		{			
			if(!SatisfyCommon(vecSatisfiedClasses, iPosition))
			{
				// [rad] this property does not apply

				refValue = "";
				return(false);
			}
		}

		// [rad] go through possible data types..

		if(!refTo.compare("RING_SIZE"))
		{
			ConvertInt(pRing->Size(), refValue);
		}
		else if(!refTo.compare("RING_IS_AROMATIC"))
		{
			ConvertBool(pRing->IsAromatic(), refValue);
		}
		else if(!refTo.compare("RING_IS_HOMOCYCLIC"))
		{
			OpenBabel::OBMol* pMolecule = pRing->GetParent();
			OpenBabel::OBAtom* pAtom;

			bool bHomoCyclic = true;

			std::vector<int>::iterator iter_path = pRing->_path.begin();
			while(iter_path != pRing->_path.end())
			{
				pAtom = pMolecule->GetAtom((*iter_path));

				if(pAtom)
				{
					if(6 != pAtom->GetAtomicNum())
					{
						bHomoCyclic = false;
						break;
					}
				}

				iter_path++;
			}

			ConvertBool(bHomoCyclic, refValue);
		}
		else if(!refTo.compare("RING_IS_HETEROCYCLIC"))
		{
			OpenBabel::OBMol* pMolecule = pRing->GetParent();
			OpenBabel::OBAtom* pAtom;

			bool bHeteroCyclic = false;

			std::vector<int>::iterator iter_path = pRing->_path.begin();
			while(iter_path != pRing->_path.end())
			{
				pAtom = pMolecule->GetAtom((*iter_path));

				if(pAtom)
				{
					if(6 != pAtom->GetAtomicNum())
					{
						bHeteroCyclic = true;
						break;
					}
				}

				iter_path++;
			}

			ConvertBool(bHeteroCyclic, refValue);
		}
		else
		{
			// [rad] unknown datatype?
			refValue = "";
			return(false);
		}

		return(true);
	}
	//--
	bool DataProperty::Satisfy(OpenBabel::OBMol* pMolecule, 
									const std::string& refTo, 
									std::vector<Class*>& vecSatisfiedClasses, 
									std::string& refValue)
	{
		//bool bSatisfied = false;
		int iPosition = -1;

		// [rad] if we are default, we automatically satisfy		
		if(!IsDefault())
		{			
			if(!SatisfyCommon(vecSatisfiedClasses, iPosition))
			{
				// [rad] this property does not apply

				refValue = "";
				return(false);
			}
		}

		// [rad] go through possible data types..

		if(!refTo.compare("MOLECULE_ATOM_COUNT"))
		{
			ConvertInt(pMolecule->NumAtoms(), refValue);
		}
		else if(!refTo.compare("MOLECULE_BOND_COUNT"))
		{
			ConvertInt(pMolecule->NumBonds(), refValue);
		}
		else if(!refTo.compare("MOLECULE_RING_COUNT"))
		{
			std::vector<OpenBabel::OBRing*>& refSSSR = pMolecule->GetSSSR();
			ConvertInt(refSSSR.size(), refValue);
		}
		else if(!refTo.compare("MOLECULE_HEAVY_HYDROGEN_COUNT"))
		{
			ConvertInt(pMolecule->NumHvyAtoms(), refValue);
		}
		else if(!refTo.compare("MOLECULE_RESIDUE_COUNT"))
		{
			ConvertInt(pMolecule->NumResidues(), refValue);
		}
		else if(!refTo.compare("MOLECULE_ROTOR_COUNT"))
		{
			ConvertInt(pMolecule->NumRotors(), refValue);
		}
		else if(!refTo.compare("MOLECULE_FORMULA"))
		{
			refValue = pMolecule->GetFormula();
		}
		else if(!refTo.compare("MOLECULE_FORMATION_HEAT"))
		{
			ConvertDouble(pMolecule->GetEnergy(), refValue);
		}
		else if(!refTo.compare("MOLECULE_STANDARD_MOLAR_MASS"))
		{
			ConvertDouble(pMolecule->GetMolWt(), refValue);
		}
		else if(!refTo.compare("MOLECULE_EXACT_MASS"))
		{
			ConvertDouble(pMolecule->GetExactMass(), refValue);
		}
		else if(!refTo.compare("MOLECULE_TOTAL_CHARGE"))
		{
			ConvertInt(pMolecule->GetTotalCharge(), refValue);
		}
		else if(!refTo.compare("MOLECULE_SPIN_MULTIPLICITY"))
		{
			ConvertInt(pMolecule->GetTotalSpinMultiplicity(), refValue);
		}
		else if(!refTo.compare("MOLECULE_IS_CHIRAL"))
		{
			ConvertBool(pMolecule->IsChiral(), refValue);
		}
		else if(!refTo.compare("MOLECULE_HAS_AROMATIC_RING"))
		{
			std::vector<OpenBabel::OBRing*>& refSSSR = pMolecule->GetSSSR();
			bool bAromatic = false;
			std::vector<OpenBabel::OBRing*>::iterator iter_rings = refSSSR.begin();
			while(iter_rings != refSSSR.end())
			{
				if((*iter_rings)->IsAromatic())
				{
					bAromatic = true;
					break;
				}

				iter_rings++;
			}

			ConvertBool(bAromatic, refValue);
		}
		else if(!refTo.compare("MOLECULE_HAS_HOMOCYCLIC_RING"))
		{
			std::vector<OpenBabel::OBRing*>& refSSSR = pMolecule->GetSSSR();
			std::vector<OpenBabel::OBRing*>::iterator iter_rings = refSSSR.begin();
			OpenBabel::OBAtom* pAtom;

			bool bHomoCyclic = true;

			while(iter_rings != refSSSR.end())
			{
				std::vector<int>::iterator iter_path = (*iter_rings)->_path.begin();
				while(iter_path != (*iter_rings)->_path.end())
				{
					pAtom = pMolecule->GetAtom((*iter_path));

					if(pAtom)
					{
						if(6 != pAtom->GetAtomicNum())
						{
							bHomoCyclic = false;
							break;
						}
					}

					iter_path++;
				}

				if(!bHomoCyclic) break;

				iter_rings++;
			}
		
			ConvertBool(bHomoCyclic, refValue);
		}
		else if(!refTo.compare("MOLECULE_HAS_HETEROCYCLIC_RING"))
		{
			std::vector<OpenBabel::OBRing*>& refSSSR = pMolecule->GetSSSR();
			std::vector<OpenBabel::OBRing*>::iterator iter_rings = refSSSR.begin();
			OpenBabel::OBAtom* pAtom;

			bool bHeteroCyclic = false;

			while(iter_rings != refSSSR.end())
			{
				std::vector<int>::iterator iter_path = (*iter_rings)->_path.begin();
				while(iter_path != (*iter_rings)->_path.end())
				{
					pAtom = pMolecule->GetAtom((*iter_path));

					if(pAtom)
					{
						if(6 != pAtom->GetAtomicNum())
						{
							bHeteroCyclic = true;
							break;
						}
					}

					iter_path++;
				}

				if(bHeteroCyclic) break;

				iter_rings++;
			}
		
			ConvertBool(bHeteroCyclic, refValue);
		}
		else
		{
			// [rad] maybe it's a descriptor?
			if(SatisfyDescriptor(pMolecule, refTo, refValue))
			{
				return(true);
			}

			// [rad] unknown datatype?
			refValue = "";
			return(false);
		}

		return(true);
	}
void MaterialDatabaseReader::ProcessElementBeginContent()
{
    if( MATCH_ELEMENT_NAME( L"Material" ) )
    {
        m_pCurrentMaterial = nullptr;

        const WCHAR* strName = FindAttribute( L"Name" );
        if( !strName )
            return;

        m_pCurrentMaterial = new ExportMaterialDefinition();
        m_pCurrentMaterial->strName = ConvertString( strName );

        const WCHAR* strDesc = FindAttribute( L"Description" );
        if( strDesc )
            m_pCurrentMaterial->strDescription = ConvertString( strDesc );

        g_Materials.push_back( m_pCurrentMaterial );
        return;
    }
    else if( MATCH_ELEMENT_NAME( L"Parameter" ) )
    {
        if( !m_pCurrentMaterial )
            return;

        if( m_pCurrentParam )
            return;

        const WCHAR* strName = FindAttribute( L"Name" );
        if( !strName )
            return;

        m_pCurrentParam = new ExportMaterialParameterDefinition();
        m_pCurrentParam->strName = ConvertString( strName );

        m_pCurrentMaterial->Parameters.push_back( m_pCurrentParam );

        const WCHAR* strDisplayName = FindAttribute( L"DisplayName" );
        if( strDisplayName )
            m_pCurrentParam->strDisplayName = ConvertString( strDisplayName );
        else
            m_pCurrentParam->strDisplayName = m_pCurrentParam->strName;

        const WCHAR* strDesc = FindAttribute( L"Description" );
        m_pCurrentParam->strDescription = ConvertString( strDesc );

        const WCHAR* strDisplayHint = FindAttribute( L"DisplayHint" );
        if( !strDisplayHint || wcslen( strDisplayHint ) < 1 )
            m_pCurrentParam->strDisplayHint = " ";
        else
            m_pCurrentParam->strDisplayHint = ConvertString( strDisplayHint );

        const WCHAR* strLoaderHint = FindAttribute( L"LoadHint" );
        m_pCurrentParam->strLoaderHint = ConvertString( strLoaderHint );

        const WCHAR* strType = FindAttribute( L"Type" );
        m_pCurrentParam->ParamType = ConvertType( strType );

        const WCHAR* strVisible = FindAttribute( L"ToolVisible" );
        m_pCurrentParam->bVisibleInTool = ConvertBool( strVisible, false );

        const WCHAR* strExport = FindAttribute( L"Export" );
        m_pCurrentParam->bExportToContentFile = ConvertBool( strExport, true );

        const WCHAR* strDetectAlpha = FindAttribute( L"DetectAlpha" );
        m_pCurrentParam->bDetectAlpha = ConvertBool( strDetectAlpha, false );

        const WCHAR* strDefaultValue = FindAttribute( L"DefaultValue" );
        m_pCurrentParam->strDefaultValue = ConvertString( strDefaultValue );
        return;
    }
}