IF( NOT INCLUDED_MACROS )

    MACRO( MY_SWIG_ADD_MODULE NAME LANGUAGE )
        IF( ${CMAKE_VERSION} VERSION_LESS "3.9.0" )
            SWIG_ADD_MODULE( ${NAME} ${LANGUAGE} ${ARGN} )
        ELSE()
            SWIG_ADD_LIBRARY( ${NAME} LANGUAGE ${LANGUAGE} TYPE MODULE SOURCES ${ARGN} )
        ENDIF()
    ENDMACRO()

    MACRO( INSTALL_TCL_PACKAGE TARGET INDEXFILE DIR PATTERN )
        # Prepare the Tcl package index file for Release and Debug mode in the build directory.
        # Replaces the following keywords:
        # @TCL3D_VERSION@
        # @TCL_DEBUG_POSTFIX@
        SET( TCL_DEBUG_POSTFIX ${CMAKE_RELEASE_POSTFIX} )
        CONFIGURE_FILE( ${INDEXFILE} pkgIndex.Release.tcl @ONLY )
        SET( TCL_DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX} )
        CONFIGURE_FILE( ${INDEXFILE} pkgIndex.Debug.tcl @ONLY )

        # Install all Tcl-only package files.
        # This statement must be executed before copying the pkgIndex.tcl
        # files, as we still have the original pkgIndex.tcl files.
        INSTALL(
            DIRECTORY   ${DIR}
            DESTINATION ${TCL3D_INST_DIR}/${TARGET}
            FILES_MATCHING PATTERN ${PATTERN}
        )

        # Install the configuration specific Tcl package index file.
        INSTALL(
            FILES ${CMAKE_CURRENT_BINARY_DIR}/pkgIndex.Debug.tcl
            DESTINATION ${TCL3D_INST_DIR}/${TARGET}
            RENAME pkgIndex.tcl
            CONFIGURATIONS Debug
        )
        INSTALL(
            FILES ${CMAKE_CURRENT_BINARY_DIR}/pkgIndex.Release.tcl
            DESTINATION ${TCL3D_INST_DIR}/${TARGET}
            RENAME pkgIndex.tcl
            CONFIGURATIONS Release
        )
    ENDMACRO()

  MACRO(CHECK_LIBRARY var name dirs)
    SET(${var} NOTFOUND CACHE INTERNAL "Internal" FORCE)
    FIND_LIBRARY(${var} ${name} PATHS ${${dirs}} NO_DEFAULT_PATH)
    FIND_LIBRARY(${var} ${name})
    IF(${var})
      MESSAGE(STATUS "Check for ${name}: ${${var}}")
    ELSE(${var})
      MESSAGE(FATAL_ERROR "Check for ${name}: not found in ${${dirs}}")
    ENDIF(${var})
  ENDMACRO(CHECK_LIBRARY var name dirs)

  MACRO(CHECK_PATH var name dirs)
    SET(${var} NOTFOUND CACHE INTERNAL "Internal" FORCE)
    FIND_PATH(${var} ${name} PATHS ${${dirs}} NO_DEFAULT_PATH)
    FIND_PATH(${var} ${name})
    IF(${var})
      MESSAGE(STATUS "Check for ${name}: ${${var}}")
    ELSE(${var})
      MESSAGE(FATAL_ERROR "Check for ${name}: not found in ${${dirs}}")
    ENDIF(${var})
  ENDMACRO(CHECK_PATH var name dirs)

  MACRO( BUILD_EXECUTABLE TARGET )
    FIND_SOURCES( MY_SOURCES ${ARGN})
    ADD_EXECUTABLE( ${TARGET} ${MY_SOURCES} )
    IF( MSVC )
      # If using VisualStudio greater than VS 2010 we need to add
      # a linker flag to indicate, that MatrixLock has no safe exception handlers.
      IF( ${MSVC_VERSION} GREATER 1600 ) 
        MESSAGE( STATUS "${TARGET}: Adding linker options: -SAFESEH:NO" )
        SET_TARGET_PROPERTIES( ${TARGET} PROPERTIES LINK_FLAGS "-SAFESEH:NO")
      ENDIF()
    ENDIF()
    TARGET_LINK_LIBRARIES( ${TARGET} ${SYS_LIBS} )
    INSTALL( TARGETS ${TARGET} DESTINATION bin )
  ENDMACRO( BUILD_EXECUTABLE TARGET )

  MACRO( BUILD_LIBRARY TARGET )
    FIND_SOURCES( MY_SOURCES ${ARGN} )
    ADD_LIBRARY( ${TARGET} SHARED ${MY_SOURCES} )
    IF( MSVC )
      # If using VisualStudio greater than VS 2010 and OpenSceneGraph 3.0.1
      # we must add the force multile linker option, because of osgDB::fstream and VS bug.
      IF( ${MSVC_VERSION} GREATER 1600 ) 
        MESSAGE( STATUS "${TARGET}: Adding linker option -FORCE:Multiple -SAFESEH:NO" )
        SET_TARGET_PROPERTIES( ${TARGET} PROPERTIES POSTFIX "-${TCL3D_VERSION}" LINK_FLAGS "-FORCE:Multiple -SAFESEH:NO")
      ENDIF()
    ENDIF()
    TARGET_LINK_LIBRARIES( ${TARGET} ${TCL_STUB_LIBRARY} ${TK_STUB_LIBRARY} ${SYS_LIBS} )
    INSTALL( TARGETS ${TARGET} DESTINATION lib${PLATFORM_TYPE_STRING} )
  ENDMACRO( BUILD_LIBRARY TARGET )

  MACRO( UNIQUE var_name list )
    # Make the given list have only one instance of each unique element and
    # store it in var_name.
    SET(unique_tmp "")
    FOREACH(l ${list})
#       MESSAGE(STATUS "UNIQUE: checking for ${l} in (${unique_tmp})")
      IF(NOT "${unique_tmp}" MATCHES "(^|;)${l}(;|$)")
        SET(unique_tmp ${unique_tmp} ${l})
#       ELSE(NOT "${unique_tmp}" MATCHES "(^|;)${l}(;|$)")
#         MESSAGE(STATUS "UNIQUE: Don't append ${l}")
      ENDIF(NOT "${unique_tmp}" MATCHES "(^|;)${l}(;|$)")
    ENDFOREACH(l)
    SET(${var_name} ${unique_tmp})
  ENDMACRO(UNIQUE)

  MACRO(UNIQUE_FILE var_name list)
    # Make the given list have only one instance of each unique element and
    # store it in var_name.
    SET(unique_tmp "")
    FOREACH(l ${list})
#       MESSAGE(STATUS "UNIQUE_FILE: checking for ${l} in (${unique_tmp})")
      SET(found FALSE)
      FOREACH(u ${unique_tmp})
        IF(${u} STREQUAL ${l})
          SET(found TRUE)
        ENDIF(${u} STREQUAL ${l})
      ENDFOREACH(u)
      IF(NOT found)
        SET(unique_tmp ${unique_tmp} ${l})
#       ELSE(NOT found)
#         MESSAGE(STATUS "UNIQUE_FILE: Don't append ${l}")
      ENDIF(NOT found)
    ENDFOREACH(l)
    SET(${var_name} ${unique_tmp})
  ENDMACRO(UNIQUE_FILE)

  MACRO( FIND_SOURCES var )
    SET( ALL_SOURCES "" ) # Clear variable (important if more than one targets inside one CMakeLists.txt)
    SET(ARGUMENTS ${ARGN})
    IF(${ARGC} GREATER 1)
      STRING(TOUPPER ${ARGV1} LIB_TYPE)
      IF(${LIB_TYPE} STREQUAL "STATIC" OR ${LIB_TYPE} STREQUAL "SHARED")
        LIST(REMOVE_AT ARGUMENTS 0)
      ENDIF(${LIB_TYPE} STREQUAL "STATIC" OR ${LIB_TYPE} STREQUAL "SHARED")
    ENDIF(${ARGC} GREATER 1)
    SET(ARG_COUNT 0)
    LIST(LENGTH ARGUMENTS ARG_COUNT)
    IF( ${ARG_COUNT} EQUAL 0 )
      FILE( GLOB MY_SOURCES ./*.c ./*.cpp ./*.h )
      SET( ALL_SOURCES ${ALL_SOURCES} ${MY_SOURCES} )
    ELSE( ${ARG_COUNT} EQUAL 0 )
      FOREACH( ELEMENT ${ARGUMENTS} )
        SET( MY_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${ELEMENT} )
        IF( IS_DIRECTORY ${MY_PATH} )
          FILE( GLOB MY_SOURCES ${MY_PATH}/*.c ${MY_PATH}/*.cpp ${MY_PATH}/*.h )
          SET( ALL_SOURCES ${ALL_SOURCES} ${MY_SOURCES} )
        ELSE( IS_DIRECTORY ${MY_PATH} )
          SET( ALL_SOURCES ${ALL_SOURCES} ${ELEMENT} )
        ENDIF( IS_DIRECTORY ${MY_PATH} )
      ENDFOREACH( ELEMENT ${ARGUMENTS} )
    ENDIF( ${ARG_COUNT} EQUAL 0 )
    SET( ${ARGV0} ${ALL_SOURCES} )
  ENDMACRO( FIND_SOURCES var )

  MACRO(ADD_SOURCE_GROUP GROUP_NAME PATH)
    FILE( GLOB FileList ${PATH}/* )
    SOURCE_GROUP( ${GROUP_NAME} FILES ${FileList} )
  ENDMACRO(ADD_SOURCE_GROUP)

  # Run gcc compiler with "-dumpversion" and parse major/minor version with a regex.
  FUNCTION(GET_GCC_VERSION COMPILER_VERSION)
    EXEC_PROGRAM(${CMAKE_CXX_COMPILER}
      ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion
      OUTPUT_VARIABLE _COMPILER_VERSION
    )
    STRING(REGEX REPLACE "([0-9])\\.([0-9])(\\.[0-9])?" "\\1.\\2"
      _COMPILER_VERSION ${_COMPILER_VERSION})

    SET(${COMPILER_VERSION} ${_COMPILER_VERSION} PARENT_SCOPE)
  ENDFUNCTION()

  SET( INCLUDED_MACROS TRUE )
ENDIF( NOT INCLUDED_MACROS )
