--- a
+++ b/trunk/Cm/Cm.Core/Function.cpp
@@ -0,0 +1,101 @@
+#include <Cm.Core/Function.hpp>
+#include <Cm.Core/Assert.hpp>
+#include <Cm.Core/ConversionTable.hpp>
+#include <Cm.Core/TypeChecker.hpp>
+#include <iostream>
+namespace Cm { namespace Core {
+
+Function::Function(const String& name_, const Position& pos_, const ScopePtr& parentScope_, const String& functionSetName_, 
+    const EntityPtr& returnTypeExpr_, const ParameterListPtr& parameters_, const CompoundStatementPtr& body_): 
+    Entity(name_, pos_, parentScope_), functionSetName(functionSetName_), returnTypeExpr(returnTypeExpr_), parameters(parameters_), 
+    conversion(IMPLICIT_CONVERSION), body(body_), called(false)
+{
+}
+
+void Function::TypeCheck()
+{
+    if (!TypeChecked())
+    {
+        Entity::TypeCheck();
+        if (returnTypeExpr)
+        {
+            TypeChecker::TypeCheck(returnTypeExpr);
+            returnType = returnTypeExpr->GetType();
+        }
+        parameters->TypeCheck();
+        body->TypeCheck();
+    }
+}
+
+void Function::AddToScope()
+{
+    ParentScope()->AddFunction(boost::static_pointer_cast<Function>(shared_from_this()));
+}
+
+bool Function::IsConversion() const
+{
+    return IsConstructor() && conversion == IMPLICIT_CONVERSION && Parameters().Count() == 2 && 
+        Parameters()[0]->TypeExpr()->FullName() != Parameters()[1]->TypeExpr()->FullName();
+}
+
+bool Function::FindConversions(const ArgumentVector& arguments, ResolutionOption resolutionOption, FunctionListPtr& conversions, int& numConversions) 
+{
+    TypeCheck();
+    CM_CORE_ASSERT(Parameters().Count() == arguments.size());
+    int n = Parameters().Count();
+    for (int i = 0; i < n; ++i)
+    {
+        Argument sourceArgument = arguments[i];
+        TypePtr sourceArgumentType = sourceArgument.Type();
+        if (sourceArgumentType->IsFunctionSetType())
+        {
+            conversions->Append(FunctionPtr());
+            continue;
+        }
+        String sourceTypeName = sourceArgumentType->FullName();
+        TypePtr targetType = Parameters()[i]->GetType();
+        if (!targetType)
+        {
+            int x = 0;
+        }
+        CM_CORE_ASSERT(targetType);
+        String targetTypeName = targetType->FullName();
+        if (sourceTypeName == targetTypeName)
+        {
+            if (targetType->IsReferenceType() && sourceArgument.Category() != LVALUE)
+            {
+                return false;
+            }
+            if (targetType->IsConstType() && sourceArgument.Category() == LVALUE)
+            {
+                //++numConversions;   //  do not count lvalue to rvalue conversion 
+            }
+            conversions->Append(FunctionPtr());
+        }
+        else
+        {
+            if (resolutionOption == ALLOW_TRIVIAL_CONVERSIONS || resolutionOption == DENY_LEFT_CONVERSION && i == 0)
+            {
+                return false;
+            }
+            FunctionPtr conversion = ConversionTable::Instance()->GetConversion(sourceTypeName, targetTypeName);
+            if (conversion)
+            {
+                conversions->Append(conversion);
+                ++numConversions;
+            }
+            else
+            {
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+void Function::MarkCalledFunctions()
+{
+    body->MarkCalledFunctions();
+}
+
+} } // namespace Cm::Core