You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@reef.apache.org by we...@apache.org on 2015/01/29 21:43:00 UTC

[16/31] incubator-reef git commit: [REEF-97] Add the REEF.NET code base

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/AbstractNode.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/AbstractNode.cs b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/AbstractNode.cs
new file mode 100644
index 0000000..a88e7d2
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/AbstractNode.cs
@@ -0,0 +1,131 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using Org.Apache.Reef.Tang.Types;
+using Org.Apache.Reef.Tang.Util;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+    public class AbstractNode : INode
+    {
+        /// It is from Type.FullName. This name is used as Name in a Node. 
+        /// It is not unique for a generic type with different type of arguments.
+        /// It is used for toString or debug info as AssemblyQualifiedName is really long
+        private String name;
+
+        /// It is from Type.AssemblyQualifiedName. THis name is used as full name in a Node
+        /// It is unique for a generic type with different type of arguments.
+        private String fullName; //it comes from 
+
+        //parent node in the class hierarchy
+        private INode parent; 
+        
+        //children in the class hierarchy
+        protected IDictionary<String, INode> children = new MonotonicTreeMap<string, INode>();
+
+        public AbstractNode(INode parent, String name, String fullName)
+        {
+            this.parent = parent;
+            this.name = name;
+            this.fullName = fullName;
+            if (parent != null)
+            {
+                parent.Add(this);
+            }
+        }
+
+        public ICollection<INode> GetChildren()
+        {
+            return children.Values;
+        }
+
+        public bool Contains(String key) 
+        {
+            return children.ContainsKey(key);
+        }
+
+        public INode Get(String key)
+        {
+            INode val;
+            if (children.TryGetValue(key, out val))
+            {
+                return val;
+            }
+            return null;
+        }
+
+        public virtual void Add(INode n)
+        {
+            children.Add(n.GetFullName(), n);
+        }
+
+        public string GetFullName()
+        {
+            return fullName;
+        }
+
+        public string GetName()
+        {
+            return name;
+        }
+
+        public INode GetParent()
+        {
+            return parent;
+        }
+
+        public override bool Equals(Object o) 
+        {
+            if(o == null) return false;
+            if(o == this) return true;
+    
+            AbstractNode n = (AbstractNode) o;
+            bool parentsEqual;
+            if (n.parent == this.parent) {
+                parentsEqual = true;
+            } else if (n.parent == null) {
+                parentsEqual = false;
+            } else if (this.parent == null) {
+                parentsEqual = false;
+            } else {
+                parentsEqual = n.parent.Equals(this.parent);
+            }
+            if (!parentsEqual) {
+                return false;
+            }
+            return fullName.Equals(n.fullName);
+        }
+
+        public override int GetHashCode()
+        {
+            return fullName.GetHashCode();
+        }
+
+        public override String ToString()
+        {
+            return "[" + this.GetType().FullName + " '" + fullName + "']";
+        }
+
+        public int CompareTo(INode n)
+        {
+            return fullName.CompareTo(n.GetFullName());
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ClassHierarchyImpl.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ClassHierarchyImpl.cs b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ClassHierarchyImpl.cs
new file mode 100644
index 0000000..3f9f16e
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ClassHierarchyImpl.cs
@@ -0,0 +1,526 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using Org.Apache.Reef.Utilities.Logging;
+using Org.Apache.Reef.Tang.Annotations;
+using Org.Apache.Reef.Tang.Exceptions;
+using Org.Apache.Reef.Tang.Interface;
+using Org.Apache.Reef.Tang.Types;
+using Org.Apache.Reef.Tang.Util;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+    public class ClassHierarchyImpl : ICsClassHierarchy
+    {
+        private static readonly Logger LOGGER = Logger.GetLogger(typeof (ClassHierarchyImpl));
+        private INode rootNode;
+        private MonotonicTreeMap<String, INamedParameterNode> shortNames = new MonotonicTreeMap<String, INamedParameterNode>();
+        private IList<string> assemblies;
+        private AssemblyLoader loader = null;
+
+        public ParameterParser Parameterparser = new ParameterParser();
+
+        public ClassHierarchyImpl(String file) : this(new string[] { file }, new Type[0])
+        {
+        }
+
+        public ClassHierarchyImpl(string[] assemblies) : this(assemblies, new Type[0])
+        {
+        }
+
+        //parameterParsers are classes that extends from IExternalConstructor
+        public ClassHierarchyImpl(string[] assemblies, Type[] parameterParsers)  
+        {
+            this.assemblies = assemblies;
+            rootNode = NodeFactory.CreateRootPackageNode();
+            loader = new AssemblyLoader(assemblies);
+           
+            foreach (Type p in parameterParsers) //p must be extend from IExternalConstructor
+            {
+                try 
+                {
+                    Parameterparser.AddParser(p);
+                } 
+                catch (BindException e)
+                {
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new ArgumentException("Could not register parameter parsers", e), LOGGER);
+                }
+            }
+
+            foreach (var a in loader.Assemblies)
+            {
+                foreach (var t in a.GetTypes())
+                {
+                    RegisterType(t);
+                }
+            }
+        }
+
+        public INode RegisterType(string assemblyQualifiedName)
+        {
+            Type type = this.loader.GetType(assemblyQualifiedName);
+            if (type != null)
+            {
+                return RegisterType(type);
+            }
+            return null;
+        }
+
+        public INode RegisterType(Type type)
+        {
+            if (ReflectionUtilities.IsAnnonymousType(type))
+            {
+                // DevNote: Kinda hacky way to indicate the no-op case.
+                return rootNode;
+            }
+
+            INode n = GetAlreadyBoundNode(type);
+            if (n != null)
+            {
+                return n;
+            }
+
+            if (type.BaseType != null)
+            {
+                RegisterType(type.BaseType);
+            }
+
+            foreach (Type interf in type.GetInterfaces())
+            {
+                RegisterType(ReflectionUtilities.EnsureInterfaceType(interf));
+            }
+
+            Type enclosingClass = type.DeclaringType; // this.GetEnclosingClass(type);
+            if (enclosingClass != null)
+            {
+                RegisterType(enclosingClass);
+            }
+
+            INode node = RegisterClass(type);
+
+            foreach (Type inner in type.GetNestedTypes())
+            {
+                RegisterType(inner);
+            }
+
+            IClassNode classNode = node as ClassNodeImpl;
+            if (classNode != null)
+            {
+                foreach (IConstructorDef constructorDef in classNode.GetInjectableConstructors())
+                {
+                    foreach (IConstructorArg constructorArg in constructorDef.GetArgs())
+                    {
+                        if (constructorArg.Gettype() == null)
+                        {
+                            Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new ArgumentException("not type in arg"), LOGGER);
+                        }
+                        RegisterType(constructorArg.Gettype());  //Gettype returns param's Type.fullname
+                        if (constructorArg.GetNamedParameterName() != null)
+                        {
+                            INamedParameterNode np = (INamedParameterNode)RegisterType(constructorArg.GetNamedParameterName());
+                            try
+                            {
+                                if (np.IsSet() || np.IsList())
+                                {
+                                    //throw new NotImplementedException();
+                                }
+                                else
+                                {
+                                    if (!ReflectionUtilities.IsCoercable(ClassForName(constructorArg.Gettype()), ClassForName(np.GetFullArgName())))
+                                    {
+                                        var e = new ClassHierarchyException(
+                                            "Named parameter type mismatch in " + classNode.GetFullName() + ".  Constructor expects a "
+                                                + constructorArg.Gettype() + " but " + np.GetName() + " is a "
+                                                + np.GetFullArgName());
+                                        Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER);
+                                    }
+                                }
+                            }
+                            catch (TypeLoadException e)
+                            {
+                                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+                                var ex = new ClassHierarchyException("Constructor refers to unknown class "
+                                    + constructorArg.GetType(), e);
+                                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+                            }
+                        }
+                    }
+                }
+            }
+            else
+            {
+                INamedParameterNode npNode = node as INamedParameterNode;
+                if (npNode != null)
+                {
+                    RegisterType(npNode.GetFullArgName());
+                }
+            }
+            
+            return node;
+        }
+
+        private INode RegisterClass(Type type)
+        {
+            INode node = GetAlreadyBoundNode(type);
+            if (node != null)
+            {
+                return node;
+            }
+
+            node = BuildPathToNode(type);
+            IClassNode classNode = node as IClassNode;
+            if (classNode != null)
+            {
+                Type baseType = type.BaseType;
+                if (baseType != null)
+                {
+                    IClassNode n = (IClassNode) GetAlreadyBoundNode(baseType);
+                    if (n != null)
+                    {
+                        n.PutImpl(classNode);
+                    }
+                    else
+                    {
+                        Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Error in finding Node for BaseType"), LOGGER);
+                    }
+                }
+
+                foreach (Type interf in ReflectionUtilities.GetInterfaces(type, false))
+                {
+                    IClassNode n = (IClassNode)GetAlreadyBoundNode(ReflectionUtilities.EnsureInterfaceType(interf));
+                    if (n != null)
+                    {
+                        n.PutImpl(classNode);
+                    }
+                    else
+                    {
+                        Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Error in finding Node for Interface"), LOGGER);
+                    }
+                }
+            }
+            return node;
+        }
+
+        public INode BuildPathToNode(Type type)
+        {
+            INode parent = GetParentNode(type);
+
+            Type argType = ReflectionUtilities.GetNamedParameterTargetOrNull(type);
+
+            if (argType == null)
+            {
+                return NodeFactory.CreateClassNode(parent, type);
+            }
+            INamedParameterNode np = NodeFactory.CreateNamedParameterNode(parent, type, argType);
+
+            if(Parameterparser.CanParse(ReflectionUtilities.GetAssemblyQualifiedName(argType))) {
+                if(type.GetCustomAttribute<NamedParameterAttribute>().DefaultClass != null) 
+                {
+                    var e = new ClassHierarchyException("Named parameter " + ReflectionUtilities.GetAssemblyQualifiedName(type) + " defines default implementation for parsable type " + ReflectionUtilities.GetAssemblyQualifiedName(argType));
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER);
+                }
+            }
+
+            string shortName = np.GetShortName();
+            if (shortName != null && !shortName.Equals(""))
+            {
+                INamedParameterNode oldNode = null;
+                shortNames.TryGetValue(shortName, out oldNode);
+                if (oldNode != null)
+                {
+                    if (oldNode.GetFullName().Equals(np.GetFullName()))
+                    {
+                        var ex = new IllegalStateException("Tried to double bind "
+                            + oldNode.GetFullName() + " to short name " + shortName);
+                        Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+                    }
+                    var e = new ClassHierarchyException("Named parameters " + oldNode.GetFullName()
+                        + " and " + np.GetFullName() + " have the same short name: "
+                        + shortName);
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER);
+                }
+                shortNames.Add(shortName, np);
+
+            }
+            return np;            
+        }
+
+        //return Type T if type implements Name<T>, null otherwise
+        //e.g. [NamedParameter(typeof(System.String), "Number of seconds to sleep", "10", "sec")]
+        //class Seconds : Name<Int32> { }
+        //return Int32
+
+        //TODO add error handlings
+        public Type GetNamedParameterTargetOrNull(Type type)
+        {
+            var npAnnotation = type.GetCustomAttribute<NamedParameterAttribute>();
+            if (npAnnotation != null)
+            {
+                Type[] intfs = type.GetInterfaces();
+                if (intfs.Length == 1)
+                {
+                    if (intfs[0].Name.Equals(GetNameOfNameInterface()))
+                    {
+                        Type[] args = intfs[0].GetGenericArguments();
+                        if (args.Length == 1)
+                        {
+                            return args[0];
+                        }
+                    }
+                }
+
+            }
+            return null;   
+        }
+
+        private INode GetAlreadyBoundNode(Type t)
+        {
+            //get outclass names including itsself
+            string[] outerClassNames = ReflectionUtilities.GetEnclosingClassNames(t);
+
+            INode current = rootNode;
+            for (int i = 0; i < outerClassNames.Length; i++)            
+            {
+                current = current.Get(outerClassNames[i]);
+                if (current == null)
+                {
+                    StringBuilder sb = new StringBuilder();
+                    for (int j = 0; j <= i; j++)
+                    {
+                        sb.Append(outerClassNames[j]);
+                        if (j != i)
+                        {
+                            sb.Append(".");
+                        }
+                    }
+                    return null;
+                    //throw new NameResolutionException(t.FullName, sb.ToString());
+                }
+
+            }
+            return current; 
+        }
+
+        //starting from the root, get child for each eclosing class excluding the type itsself
+        //all enclosing classes should be already in the hierarchy
+        //Type B2 = asm.GetType(@"Org.Apache.Reef.Tang.Examples.B+B1+B2");
+        //string[] pathB2 = ClassNameParser.GetEnclosingClassShortNames(B2);
+        //Assert.AreEqual(pathB2[0], "B");
+        //Assert.AreEqual(pathB2[1], "B1");
+        //Assert.AreEqual(pathB2[2], "B2");
+        //return INode for B1
+        private INode GetParentNode(Type type)
+        {
+            INode current = rootNode;
+            string[] enclosingPath = ReflectionUtilities.GetEnclosingClassNames(type);
+            for (int i = 0; i < enclosingPath.Length - 1; i++)
+            {
+                current = current.Get(enclosingPath[i]);
+            }
+            return current;
+        }
+
+        private string GetNameOfNameInterface()
+        {
+            var tn = typeof(Name<int>);
+            return tn.Name;
+        }
+
+        public INode GetNode(string fullName)
+        {
+            Type t = loader.GetType(fullName);
+
+            if (t == null)
+            {
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new NameResolutionException(fullName, fullName), LOGGER);
+            }
+
+            return this.GetNode(t);
+        }
+
+        public INode GetNode(Type type)
+        {
+            this.RegisterType(type);
+            return GetAlreadyBoundNode(type);
+        }
+
+        public INode GetNamespace()
+        {
+            return rootNode;
+        }
+
+        public bool IsImplementation(IClassNode inter, IClassNode impl)
+        {
+            return impl.IsImplementationOf(inter);
+        }
+
+        public IClassHierarchy Merge(IClassHierarchy ch)
+        {
+            if (this == ch) { return this; }
+
+            if (!(ch is ClassHierarchyImpl)) 
+            {
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new NotSupportedException("Can't merge java and non-java class hierarchies yet!"), LOGGER);
+            }
+
+            if(this.assemblies.Count == 0) 
+            {
+                return ch;
+            }
+    
+            ClassHierarchyImpl chi = (ClassHierarchyImpl)ch;
+            MonotonicHashSet<string> otherJars = new MonotonicHashSet<string>();
+            otherJars.AddAll(chi.assemblies);
+            MonotonicHashSet<string> myJars = new MonotonicHashSet<string>();
+            myJars.AddAll(this.assemblies);
+            if(myJars.ContainsAll(otherJars)) 
+            {
+                return this;
+            } 
+            if (otherJars.ContainsAll(myJars)) 
+            {
+                return ch;
+            } 
+            myJars.AddAll(otherJars);
+            return new ClassHierarchyImpl(myJars.ToArray());
+        }
+
+        public object Parse(INamedParameterNode np, string value)
+        {
+            IClassNode iface = null;
+            try 
+            {
+                iface = (IClassNode)GetNode(np.GetFullArgName());
+            } 
+            catch(NameResolutionException e) 
+            {
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+                var ex = new IllegalStateException("Could not parse validated named parameter argument type.  NamedParameter is " + np.GetFullName() + " argument type is " + np.GetFullArgName(), e);
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+            }
+            Type clazz;
+            String fullName;
+            try 
+            {
+                clazz = (Type)ClassForName(iface.GetFullName());
+                fullName = null;
+            } 
+            catch(TypeLoadException e) 
+            {
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Warning, LOGGER);
+                clazz = null;
+                fullName = iface.GetFullName();
+            }
+
+            object result = null;
+            if (clazz != null) 
+            {
+                result = Parameterparser.Parse(clazz, value);
+            }
+            else
+            {
+                result = Parameterparser.Parse(fullName, value);                
+            }
+
+            if (result == null)
+            {
+                try
+                {
+                    INode impl = GetNode(value);
+                    if (impl is IClassNode)
+                    {
+                        if (IsImplementation(iface, (IClassNode) impl))
+                        {
+                            return impl;
+                        }
+                    }
+                    var ex =
+                        new ParseException(
+                            "Name<" + iface.GetFullName() + "> " + np.GetFullName() + " cannot take non-subclass " +
+                            impl.GetFullName());
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+                }
+                catch (NameResolutionException ec)
+                {
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(ec, Level.Error, LOGGER);
+                    var ex =
+                        new ParseException(
+                            "Name<" + iface.GetFullName() + "> " + np.GetFullName() + " cannot take non-class " + value,
+                            ec);
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+                }
+            }
+            return result; 
+        }
+
+        public object ParseDefaultValue(INamedParameterNode name)
+        {
+            string[] vals = name.GetDefaultInstanceAsStrings();
+            object[] ret = new Object[vals.Length];
+            for (int i = 0; i < vals.Length; i++)
+            {
+                string val = vals[i];
+                try
+                {
+                    ret[i] = Parse(name, val);
+                }
+                catch (ParseException e)
+                {
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+                    var ex = new ClassHierarchyException("Could not parse default value " + val, e);
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+                }
+            }
+            if (name.IsSet())
+            {
+                return new HashSet<object>(ret.ToList<object>());
+            }
+            if (name.IsList())
+            {
+                return new List<object>(ret.ToList<object>());
+            }
+            if (ret.Length == 0)
+            {
+                return null;
+            }
+            if (ret.Length == 1)
+            {
+                return ret[0];
+            }
+            var ec = new IllegalStateException("Multiple defaults for non-set named parameter! " + name.GetFullName());
+            Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ec, LOGGER);
+            return null; //this line would be never reached as Throw will throw an exception
+        }
+
+        public Type ClassForName(string name)
+        {
+            return this.GetType(name);
+        }
+
+        public Type GetType(string name)
+        {
+            return this.loader.GetType(name);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ClassNodeImpl.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ClassNodeImpl.cs b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ClassNodeImpl.cs
new file mode 100644
index 0000000..27a57b9
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ClassNodeImpl.cs
@@ -0,0 +1,157 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Org.Apache.Reef.Utilities.Logging;
+using Org.Apache.Reef.Tang.Exceptions;
+using Org.Apache.Reef.Tang.Types;
+using Org.Apache.Reef.Tang.Util;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+    public class ClassNodeImpl : AbstractNode, IClassNode
+    {
+        private static readonly Logger LOGGER = Logger.GetLogger(typeof(ClassNodeImpl));
+
+        private readonly bool injectable;
+        private readonly bool unit;
+        private readonly bool externalConstructor;
+        private readonly IList<IConstructorDef> injectableConstructors;
+        private readonly IList<IConstructorDef> allConstructors;
+        private readonly MonotonicSet<IClassNode> knownImpls;
+        private readonly String defaultImpl;
+
+        public ClassNodeImpl(INode parent, String simpleName, String fullName,
+            bool unit, bool injectable, bool externalConstructor,
+            IList<IConstructorDef> injectableConstructors,
+            IList<IConstructorDef> allConstructors,
+            String defaultImplementation)
+            : base(parent, simpleName, fullName)
+        {
+
+            this.unit = unit;
+            this.injectable = injectable;
+            this.externalConstructor = externalConstructor;
+            this.injectableConstructors = injectableConstructors;
+            this.allConstructors = allConstructors;
+            this.knownImpls = new MonotonicSet<IClassNode>();
+            this.defaultImpl = defaultImplementation;
+        }
+
+        public IList<IConstructorDef> GetInjectableConstructors()
+        {
+            return injectableConstructors;
+        }
+
+        public IList<IConstructorDef> GetAllConstructors()
+        {
+            return allConstructors;
+        }
+
+        public bool IsInjectionCandidate()
+        {
+            return injectable;
+        }
+
+        public bool IsExternalConstructor()
+        {
+            return externalConstructor;
+        }
+
+        public override String ToString()
+        {
+            StringBuilder sb = new StringBuilder(base.ToString() + ": ");
+            if (GetInjectableConstructors() != null)
+            {
+                foreach (IConstructorDef c in GetInjectableConstructors())
+                {
+                    sb.Append(c.ToString() + ", ");
+                }
+            }
+            else
+            {
+                sb.Append("OBJECT BUILD IN PROGRESS!  BAD NEWS!");
+            }
+            return sb.ToString();
+        }
+
+        public IConstructorDef GetConstructorDef(IList<IClassNode> paramTypes)
+        {
+            if (!IsInjectionCandidate())
+            {
+                var e = new BindException("Cannot @Inject non-static member/local class: "
+                + GetFullName());
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER);
+            }
+            foreach (IConstructorDef c in GetAllConstructors())
+            {
+                if (c.TakesParameters(paramTypes))
+                {
+                    return c;
+                }
+            }
+            Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new BindException("Could not find requested constructor for class " + GetFullName()), LOGGER);
+            return null; // this line would not be reached as Thrwo throws an exception 
+        }
+
+        public void PutImpl(IClassNode impl)
+        {
+            knownImpls.Add(impl);
+        }
+
+        public ISet<IClassNode> GetKnownImplementations()
+        {
+            return new MonotonicSet<IClassNode>(knownImpls);
+        }
+
+        public bool IsUnit()
+        {
+            return unit;
+        }
+
+        public bool IsImplementationOf(IClassNode inter)
+        {
+            List<IClassNode> worklist = new List<IClassNode>();
+            if (this.Equals(inter))
+            {
+                return true;
+            }
+            worklist.Add(inter);
+            while (worklist.Count != 0)
+            {
+                IClassNode cn = worklist[worklist.Count - 1];
+                worklist.RemoveAt(worklist.Count - 1);
+                ISet<IClassNode> impls = cn.GetKnownImplementations();
+                if (impls.Contains(this))
+                {
+                    return true;
+                }
+                worklist.AddRange(impls);
+            }
+            return false;
+        }
+
+        public String GetDefaultImplementation()
+        {
+            return defaultImpl;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ConstructorArgImpl.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ConstructorArgImpl.cs b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ConstructorArgImpl.cs
new file mode 100644
index 0000000..31e4103
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ConstructorArgImpl.cs
@@ -0,0 +1,97 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using Org.Apache.Reef.Tang.Types;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+    public class ConstructorArgImpl : IConstructorArg
+    {
+        private readonly String type;
+        private readonly String name;
+        private readonly bool isInjectionFuture;
+
+        public ConstructorArgImpl(String type, String namedParameterName, bool isInjectionFuture)
+        {
+            if (type == null)
+            {
+                ;
+            }
+            this.type = type;
+            this.name = namedParameterName;
+
+            //if (name != null && name.Contains(','))
+            //    throw new ApplicationException("Name contains comma : " + name);
+            this.isInjectionFuture = isInjectionFuture;
+        }
+
+        public string GetName()
+        {
+            return name == null ? type : name;
+        }
+
+        public string GetNamedParameterName()
+        {
+            return name;
+        }
+
+        public string Gettype()
+        {
+            return type;
+        }
+
+        public bool IsInjectionFuture()
+        {
+            return isInjectionFuture;
+        }
+
+        public override String ToString()
+        {
+            return name == null ? type : type + " " + name;
+        }
+
+        public override int GetHashCode()
+        {
+            return 0;
+        }
+
+        public override bool Equals(Object o)
+        {
+            ConstructorArgImpl arg = (ConstructorArgImpl)o;
+            if (!type.Equals(arg.type))
+            {
+                return false;
+            }
+            if (name == null && arg.name == null)
+            {
+                return true;
+            }
+            if (name == null && arg.name != null)
+            {
+                return false;
+            }
+            if (name != null && arg.name == null)
+            {
+                return false;
+            }
+            return name.Equals(arg.name);
+
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ConstructorDefImpl.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ConstructorDefImpl.cs b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ConstructorDefImpl.cs
new file mode 100644
index 0000000..4e72da7
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ConstructorDefImpl.cs
@@ -0,0 +1,203 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Org.Apache.Reef.Utilities.Logging;
+using Org.Apache.Reef.Tang.Exceptions;
+using Org.Apache.Reef.Tang.Types;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+    public class ConstructorDefImpl : IConstructorDef
+    {
+        private static readonly Logger LOGGER = Logger.GetLogger(typeof(ConstructorDefImpl));
+
+        private readonly IList<IConstructorArg> args = new List<IConstructorArg>();
+        private readonly String className;
+
+        public ConstructorDefImpl(String className, IConstructorArg[] args, bool injectable)
+        {
+            this.args = args;
+            this.className = className;
+            if (injectable)
+            {
+                var duplicateItems = from x in args
+                                     group x by x into grouped
+                                     where grouped.Count() > 1
+                                     select grouped.Key;
+
+                if (duplicateItems.Any())
+                {
+                    var e = new ClassHierarchyException(
+                        "Repeated constructor parameter detected.  "
+                        + "Cannot inject constructor " + ToString());
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER);
+                }
+            }
+        }
+
+        public IList<IConstructorArg> GetArgs()
+        {
+            return args;
+        }
+
+        public String GetClassName()
+        {
+            return className;
+        }
+
+        private String Join(String sep, Object[] vals)
+        {
+            if (vals.Length != 0)
+            {
+                StringBuilder sb = new StringBuilder(vals[0].ToString());
+                for (int i = 1; i < vals.Length; i++)
+                {
+                    sb.Append(sep + vals[i]);
+                }
+                return sb.ToString();
+            }
+            else
+            {
+                return "";
+            }
+        }
+
+        public override String ToString()
+        {
+            StringBuilder sb = new StringBuilder(className);
+            sb.Append("(");
+            sb.Append(Join(",", args.ToArray()));
+            sb.Append(")");
+            return sb.ToString();
+        }
+
+        // Return true if our list of args is a superset of those in def.
+        public bool IsMoreSpecificThan(IConstructorDef def)
+        {
+            // Is everything in def also in this?
+            for (int i = 0; i < def.GetArgs().Count; i++)
+            {
+                bool found = false;
+                for (int j = 0; j < this.GetArgs().Count; j++)
+                {
+                    if (GetArgs()[j].Equals(def.GetArgs()[i]))
+                    {
+                        found = true;
+                        break;
+                    }
+                }
+                // If not, then argument j from def is not in our list.  Return false.
+                if (found == false)
+                    return false;
+            }
+            // Everything in def's arg list is in ours.  Do we have at least one extra
+            // argument?
+            return GetArgs().Count > def.GetArgs().Count;
+        }
+
+        public bool TakesParameters(IList<IClassNode> paramTypes)
+        {
+            if (paramTypes.Count != args.Count)
+            {
+                return false;
+            }
+
+            int i = 0;
+            foreach (INode t in paramTypes)
+            {
+                string s;
+                if (t is INamedParameterNode)
+                {
+                    s = ((INamedParameterNode)paramTypes[i]).GetFullArgName();
+                }
+                else
+                {
+                    s = paramTypes[i].GetFullName();
+                }
+                if (!args[i].Gettype().Equals(s))
+                {
+                    return false;
+                }
+                else
+                {
+                    i++;
+                }
+
+            }
+            return true;
+        }
+
+        public override bool Equals(Object o)
+        {
+            return EqualsIgnoreOrder((IConstructorDef)o);
+        }
+
+        public override int GetHashCode()
+        {
+            return 0;
+        }
+
+        //A(int i, string j) vs. A(string i, int j) is Ambiguous in injection
+        private bool EqualsIgnoreOrder(IConstructorDef def)
+        {
+            if (GetArgs().Count != def.GetArgs().Count)
+            {
+                return false;
+            }
+            for (int i = 0; i < GetArgs().Count; i++)
+            {
+                bool found = false;
+                for (int j = 0; j < def.GetArgs().Count; j++)
+                {
+                    if (GetArgs()[i].GetName().Equals(def.GetArgs()[j].GetName()))
+                    {
+                        found = true;
+                    }
+                }
+                if (!found)
+                {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        public int CompareTo(object obj)
+        {
+            IConstructorDef o = (IConstructorDef)obj;
+            return ToString().CompareTo(o.ToString());
+        }
+
+        public bool IsInList(IList<IConstructorDef> list )
+        {
+            foreach (IConstructorDef def in list)
+            {
+                if (CompareTo(def) == 0)
+                {
+                    return true;
+                }
+
+            }
+            return false;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/NamedParameterNodeImpl.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/NamedParameterNodeImpl.cs b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/NamedParameterNodeImpl.cs
new file mode 100644
index 0000000..3bdc868
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/NamedParameterNodeImpl.cs
@@ -0,0 +1,88 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using Org.Apache.Reef.Tang.Types;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+    public class NamedParameterNodeImpl : AbstractNode, INamedParameterNode
+    {
+        private readonly String fullArgName;
+        private readonly String simpleArgName;
+        private readonly String documentation;
+        private readonly String shortName;
+        private readonly String[] defaultInstanceAsStrings;
+        private readonly bool isSet;
+        private readonly bool isList;
+
+        public NamedParameterNodeImpl(INode parent, String simpleName,
+            String fullName, String fullArgName, String simpleArgName, bool isSet, bool isList,
+            String documentation, String shortName, String[] defaultInstanceAsStrings)
+            : base(parent, simpleName, fullName)
+        {
+            this.fullArgName = fullArgName;
+            this.simpleArgName = simpleArgName;
+            this.isSet = isSet;
+            this.isList = isList;
+            this.documentation = documentation;
+            this.shortName = shortName;
+            this.defaultInstanceAsStrings = defaultInstanceAsStrings;
+        }
+
+        public override String ToString()
+        {
+            return GetSimpleArgName() + " " + GetName();
+        }
+
+        public String GetSimpleArgName()
+        {
+            return simpleArgName;
+        }
+
+        public String GetFullArgName()
+        {
+            return fullArgName;
+        }
+
+        public String GetDocumentation()
+        {
+            return documentation;
+        }
+
+        public String GetShortName()
+        {
+            return shortName;
+        }
+
+        public String[] GetDefaultInstanceAsStrings()
+        {
+            return defaultInstanceAsStrings;
+        }
+
+        public bool IsSet()
+        {
+            return isSet;
+        }
+
+        public bool IsList()
+        {
+            return isList;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/NodeFactory.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/NodeFactory.cs b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/NodeFactory.cs
new file mode 100644
index 0000000..474f2d5
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/NodeFactory.cs
@@ -0,0 +1,315 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using Org.Apache.Reef.Utilities.Logging;
+using Org.Apache.Reef.Tang.Annotations;
+using Org.Apache.Reef.Tang.Types;
+using Org.Apache.Reef.Tang.Util;
+using Org.Apache.Reef.Tang.Exceptions;
+using Org.Apache.Reef.Tang.Interface;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+    public class NodeFactory
+    {
+        private static readonly Logger LOGGER = Logger.GetLogger(typeof(NodeFactory));
+
+        public static IPackageNode CreateRootPackageNode()
+        {
+            return new PackageNodeImpl();
+        }
+
+        public static INode CreateClassNode(INode parent, Type clazz)
+        {
+            //var namedParameter = clazz.GetCustomAttribute<NamedParameterAttribute>();
+            var unit = null != clazz.GetCustomAttribute<UnitAttribute>();
+            string simpleName = ReflectionUtilities.GetName(clazz);
+            string fullName = ReflectionUtilities.GetAssemblyQualifiedName(clazz);
+            //bool isStatic = true; // clazz.IsSealed && clazz.IsAbstract; always true in C# for Java static class
+            //bool injectable = true; // always true in C#
+
+            bool isAssignableFromExternalConstructor = ReflectionUtilities.IsAssignableFromIgnoreGeneric(typeof(IExternalConstructor<>), clazz); 
+
+            //bool parentIsUnit = false; 
+
+            //No such thing in C#, should be false
+            //bool foundNonStaticInnerClass = false;
+            //foreach (Type c in clazz.getNestedTypes()) {
+            //  if (!Modifier.isStatic(c.getModifiers())) {
+            //    foundNonStaticInnerClass = true;
+            //  }
+            //}
+
+            var injectableConstructors = new List<IConstructorDef>();
+            var allConstructors = new List<IConstructorDef>();
+
+            foreach (ConstructorInfo c in clazz.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))  
+            {
+                var constructorAnnotatedInjectable = null != c.GetCustomAttribute<InjectAttribute>();
+
+                bool constructorInjectable = constructorAnnotatedInjectable;
+
+                ConstructorDefImpl constructorDef = CreateConstructorDef(c, constructorAnnotatedInjectable);
+
+                if (constructorInjectable)
+                {
+//                    if (injectableConstructors.Contains(constructorDef))
+                    if (constructorDef.IsInList(injectableConstructors))
+                    {
+                        var e = new ClassHierarchyException(
+                            "Ambiguous boundConstructors detected in class " + clazz + ": "
+                                + constructorDef + " differs from some other" + " constructor only "
+                                + "by parameter order.");
+                        Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER);
+                    }
+                    else
+                    {
+                        injectableConstructors.Add(constructorDef);
+                    }
+                }
+                allConstructors.Add(constructorDef);
+
+            }
+
+            string defaultImplementation = null;
+            DefaultImplementationAttribute defaultImpl = clazz.GetCustomAttribute<DefaultImplementationAttribute>();
+            if (null != defaultImpl)
+            {
+                Type defaultImplementationClazz = defaultImpl.Value;
+
+                if (defaultImplementationClazz == null)
+                {
+                    defaultImplementation = defaultImpl.Name;
+                }
+                else
+                {
+                    if (!ReflectionUtilities.IsAssignableFromIgnoreGeneric(clazz, defaultImplementationClazz))
+                    {
+                        var e = new ClassHierarchyException(clazz
+                                                          + " declares its default implementation to be non-subclass "
+                                                          + defaultImplementationClazz);
+                        Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER);
+                    }
+                    defaultImplementation = ReflectionUtilities.GetAssemblyQualifiedName(defaultImplementationClazz);
+                }
+            }
+            else
+            {
+                defaultImplementation = null;
+            }        
+
+            return new ClassNodeImpl(parent, simpleName, fullName, unit, true, isAssignableFromExternalConstructor, 
+                injectableConstructors, allConstructors, defaultImplementation);
+        }
+
+        //TODO
+        private static ConstructorDefImpl CreateConstructorDef(ConstructorInfo constructor, bool injectable)
+        {
+            var parameters = constructor.GetParameters();
+
+            IConstructorArg[] args = new ConstructorArgImpl[parameters.Length];
+
+            for (int i = 0; i < parameters.Length; i++)
+            {
+                //TODO for getInterfaceTarget() call
+                Type type = parameters[i].ParameterType;
+                type = ReflectionUtilities.EnsureInterfaceType(type);
+                //if (type.IsGenericType && type.FullName == null)
+                //{
+                //    type = type.GetGenericTypeDefinition();
+                //}
+                bool isFuture;
+
+                if(ReflectionUtilities.IsAssignableFromIgnoreGeneric(typeof(IInjectionFuture<>), type)) 
+                {
+                    type = ReflectionUtilities.GetInterfaceTarget(typeof(IInjectionFuture<>), type);
+                    isFuture = true;
+                } 
+                else 
+                {
+                    isFuture = false;
+                }
+
+                ParameterAttribute named = parameters[i].GetCustomAttribute<ParameterAttribute>();
+                if (named != null && !injectable)
+                {
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new ClassHierarchyException(constructor + " is not injectable, but it has an @Parameter annotation."), LOGGER);
+                }
+
+                if (type == null)
+                {
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new ApplicationException("Exception"), LOGGER);
+                }
+
+                string typename = ReflectionUtilities.GetAssemblyQualifiedName(type);
+                if (typename == null)
+                {
+                    typename = type.Name;
+                }
+                args[i] = new ConstructorArgImpl(typename, named == null ? null : ReflectionUtilities.GetAssemblyQualifiedName(named.Value), isFuture);
+            }
+            return new ConstructorDefImpl(ReflectionUtilities.GetAssemblyQualifiedName(constructor.DeclaringType), args, injectable); 
+        }
+
+        public static INamedParameterNode CreateNamedParameterNode(INode parent, Type clazz, Type argClass)
+        {
+            Type setRawArgType = ReflectionUtilities.GetInterfaceTarget(typeof(ISet<>), argClass);
+            bool isSet = setRawArgType != null;
+            if(isSet) {
+                argClass = setRawArgType;
+            }
+
+            Type listRawArgType = ReflectionUtilities.GetInterfaceTargetForType(typeof (IList<>), argClass);
+            bool isList = listRawArgType != null;
+            if (isList)
+            {
+                argClass = listRawArgType;
+            }
+
+            string simpleName = ReflectionUtilities.GetName(clazz);
+            string fullName = ReflectionUtilities.GetAssemblyQualifiedName(clazz);
+            string fullArgName = ReflectionUtilities.GetAssemblyQualifiedName(argClass);
+            string simpleArgName = ReflectionUtilities.GetName(argClass);
+
+            NamedParameterAttribute namedParameter = clazz.GetCustomAttribute<NamedParameterAttribute>();
+
+            if (namedParameter == null)
+            {
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Got name without named parameter post-validation!"), LOGGER);
+            }
+
+            bool hasStringDefault, hasClassDefault, hasStringSetDefault, hasClassSetDefault;
+            int default_count = 0;
+            //if(!namedParameter.default_value().isEmpty()) {  //QUESTION: difference from below? 
+            if (namedParameter.DefaultValue != null && namedParameter.DefaultValue.Length > 0)
+            {
+                hasStringDefault = true;
+                default_count++;
+            }
+            else
+            {
+                hasStringDefault = false;
+            }
+
+            if (namedParameter.DefaultClass != null /*Void.class*/)
+            {
+                hasClassDefault = true;
+                default_count++;
+            }
+            else
+            {
+                hasClassDefault = false;
+            }
+
+            if (namedParameter.DefaultValues != null && namedParameter.DefaultValues.Length > 0)
+            {
+                hasStringSetDefault = true;
+                default_count++;
+            }
+            else
+            {
+                hasStringSetDefault = false;
+            }
+
+            if (namedParameter.DefaultClasses != null && namedParameter.DefaultClasses.Length > 0) 
+            {
+                hasClassSetDefault = true;
+                default_count++;
+            }
+            else
+            {
+                hasClassSetDefault = false;
+            }
+
+            if (default_count > 1)
+            {
+                var e = new ClassHierarchyException("Named parameter " + fullName + " defines more than one of default_value, default_class, default_values and default_classes");
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER);
+            }
+
+            string[] defaultInstanceAsStrings = new string[]{};
+
+            if (default_count == 0)
+            {
+                defaultInstanceAsStrings = new String[] { };
+            }
+            else if (hasClassDefault)
+            {
+                Type default_class = namedParameter.DefaultClass;
+                AssertIsSubclassOf(clazz, default_class, argClass);
+                defaultInstanceAsStrings = new String[] { ReflectionUtilities.GetAssemblyQualifiedName(default_class) };
+            }
+            else if (hasStringDefault)
+            {
+                // Don't know if the string is a class or literal here, so don't bother validating.
+                defaultInstanceAsStrings = new String[] { namedParameter.DefaultValue };
+            }
+            else if (hasClassSetDefault)
+            {
+                Type[] clzs = namedParameter.DefaultClasses;
+                defaultInstanceAsStrings = new String[clzs.Length];
+                for (int i = 0; i < clzs.Length; i++)
+                {
+                    AssertIsSubclassOf(clazz, clzs[i], argClass);
+                    defaultInstanceAsStrings[i] = ReflectionUtilities.GetAssemblyQualifiedName(clzs[i]);
+                }
+            }
+            else if (hasStringSetDefault)
+            {
+                defaultInstanceAsStrings = namedParameter.DefaultValues;
+            }
+            else
+            {
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException(), LOGGER);
+            }
+
+            string documentation = namedParameter.Documentation;
+            string shortName = namedParameter.ShortName;
+            if (namedParameter.ShortName != null && namedParameter.ShortName.Length == 0)
+            {
+                shortName = null;
+            }
+
+            return new NamedParameterNodeImpl(parent, simpleName, fullName,
+                fullArgName, simpleArgName, isSet, isList, documentation, shortName, defaultInstanceAsStrings);
+        }
+
+        // private static void assertIsSubclassOf(Class<?> named_parameter, Class<?> default_class, Type argClass) {
+        private static void AssertIsSubclassOf(Type namedparameter, Type defaultclass, Type argClass)
+        {
+            bool isSubclass = false;
+            string argClassName = ReflectionUtilities.GetAssemblyQualifiedName(argClass);
+            foreach (Type t in ReflectionUtilities.ClassAndAncestors(defaultclass))
+            {
+                if (argClassName.Equals(ReflectionUtilities.GetAssemblyQualifiedName(t)))
+                {
+                    isSubclass = true;
+                }
+            }
+            if (!(isSubclass))
+            {
+                var e = new ClassHierarchyException(namedparameter + " defines a default class "
+                    + ReflectionUtilities.GetName(defaultclass) + " with a type that does not extend of its target's type " + argClass);
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/PackageNodeImpl.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/PackageNodeImpl.cs b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/PackageNodeImpl.cs
new file mode 100644
index 0000000..7516493
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/PackageNodeImpl.cs
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using Org.Apache.Reef.Tang.Types;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+    public class PackageNodeImpl : AbstractNode, IPackageNode
+    {
+        public PackageNodeImpl(INode parent, String name, String fullName) : 
+            base(parent, name, fullName)
+        {
+        }
+
+        public PackageNodeImpl()
+            : base(null, "", "[root node]")
+        {
+        }
+
+        /**
+        * Unlike normal nodes, the root node needs to take the package name of its
+        * children into account.  Therefore, we use the full name as the key when
+        * we insert nodes into the root.
+        */
+        public override void Add(INode n) {
+            if (children.Count == 289)
+            {
+                Console.WriteLine("Test");
+            }
+            children.Add(n.GetFullName(), n);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ParameterParser.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ParameterParser.cs b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ParameterParser.cs
new file mode 100644
index 0000000..840e447
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/ClassHierarchy/ParameterParser.cs
@@ -0,0 +1,199 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using Org.Apache.Reef.Utilities.Logging;
+using Org.Apache.Reef.Tang.Exceptions;
+using Org.Apache.Reef.Tang.Interface;
+using Org.Apache.Reef.Tang.Util;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+    public class ParameterParser
+    {
+        private static readonly Logger LOGGER = Logger.GetLogger(typeof(ParameterParser));
+
+        MonotonicTreeMap<String, ConstructorInfo> parsers = new MonotonicTreeMap<String, ConstructorInfo>();
+
+        //ec: ACons, tc: A
+        public void AddParser(Type ec)
+        {
+            Type tc = (Type)ReflectionUtilities.GetInterfaceTarget(typeof(IExternalConstructor<>), ec);
+            AddParser(tc, ec);
+        }
+
+        //TODO
+        //public  <T, U extends T> void AddParser(Class<U> clazz, Class<? extends ExternalConstructor<T>> ec) throws BindException {
+        //public void AddParser<T, U, V>(GenericType<U> clazz, GenericType<V> ec) 
+        //    where U : T
+        //    where V:  IExternalConstructor<T>
+        //{
+
+        //clazz: A, ec: ACons
+        private void AddParser(Type clazz, Type ec)
+        {
+            ConstructorInfo c = ec.GetConstructor(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(string) }, null);
+            
+            if (c == null)
+            {
+                var e = new BindException("Constructor " + ReflectionUtilities.GetAssemblyQualifiedName(ec) + "(String) does not exist!");
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER);
+            }
+
+            //c.setAccessible(true); //set as public 
+            parsers.Add(ReflectionUtilities.GetAssemblyQualifiedName(clazz), c);
+        }
+
+
+        public void MergeIn(ParameterParser p)
+        {
+            foreach (string s in p.parsers.Keys)
+            {
+                if (!parsers.ContainsKey(s))
+                {
+                    ConstructorInfo ci;
+                    p.parsers.TryGetValue(s, out ci);
+                    parsers.Add(s, ci);
+                }
+                else
+                {
+                    ConstructorInfo oldC;
+                    ConstructorInfo newC;
+                    parsers.TryGetValue(s, out oldC);
+                    p.parsers.TryGetValue(s, out newC);
+                    if (!oldC.Equals(newC))
+                    {
+                        var e = new ArgumentException(
+                        "Conflict detected when merging parameter parsers! To parse " + s
+                        + " I have a: " + ReflectionUtilities.GetAssemblyQualifiedName(oldC.DeclaringType)
+                        + " the other instance has a: " + ReflectionUtilities.GetAssemblyQualifiedName(newC.DeclaringType));
+                        Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(e, LOGGER);
+                    }
+                }
+            }
+        }
+
+        //(Integer, "3") return object of new Integer(3)
+        public object Parse(Type c, String s)
+        {
+            Type d = ReflectionUtilities.BoxClass(c);
+            foreach (Type e in ReflectionUtilities.ClassAndAncestors(d)) // get all the super classes of Integer for example
+            {
+                string name = ReflectionUtilities.GetAssemblyQualifiedName(e);
+                if (parsers.ContainsKey(name))
+                {
+                    object ret = Parse(name, s);
+                    if (c.IsAssignableFrom(ret.GetType())) //check if ret can be cast as c
+                    {
+                        return ret;
+                    }
+                    else
+                    {
+                        var ex = new InvalidCastException("Cannot cast from " + ret.GetType() + " to " + c);
+                        Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+                    }
+                }
+            }
+            return Parse(d.Name, s);
+        }
+
+        //name: "Integer", value: "12"
+        public object Parse(string name, string value)
+        {
+            if (parsers.ContainsKey(name))
+            {
+                try
+                {
+                    ConstructorInfo c = null;
+                    parsers.TryGetValue(name, out c);
+                    var o = c.Invoke(new object[] { value });
+                    var m = o.GetType().GetMethod("NewInstance", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
+                    return m.Invoke(o, new object[] {});
+                }
+                catch (TargetInvocationException e)
+                {
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new ArgumentException("Error invoking constructor for " + name, e), LOGGER);
+                }
+            }
+            else if (name.Equals(typeof(string).Name))
+            {
+                return (object)value;
+            }
+            if (name.Equals(typeof(Byte).Name))
+            {
+                return (object)(Byte)Byte.Parse(value);
+            }
+            if (name.Equals(typeof(Char).Name))
+            {
+                return (object)(Char)value[0];
+            }
+            if (name.Equals(typeof(short).Name))
+            {
+                return (System.Int16)System.Int16.Parse(value);
+            }
+            if (name.Equals(typeof(int).Name))
+            {
+                return (object)(Int32)Int32.Parse(value);
+            }
+            if (name.Equals(typeof(long).Name))
+            {
+                return (object)(Int64)Int64.Parse(value);
+            }
+            if (name.Equals(typeof(float).Name))
+            {
+                return (object)(Single)Single.Parse(value);
+            }
+            if (name.Equals(typeof(Double).Name))
+            {
+                return (object)(Double)Double.Parse(value);
+            }
+            if (name.Equals(typeof(Boolean).Name))
+            {
+                return (object)(Boolean)Boolean.Parse(value);
+            }
+            if (name.Equals(typeof(byte[]).Name))  
+            {
+                byte[] bytes = new byte[value.Length * sizeof(char)];
+                System.Buffer.BlockCopy(value.ToCharArray(), 0, bytes, 0, bytes.Length);
+                return bytes;
+            }
+            return null; 
+        }
+
+        private static readonly ISet<string> BUILTIN_NAMES = new HashSet<string>(new string[]
+            {
+                typeof(string).AssemblyQualifiedName, 
+                typeof(Byte).AssemblyQualifiedName,
+                typeof(char).AssemblyQualifiedName,
+                typeof(short).AssemblyQualifiedName,
+                typeof(Int32).AssemblyQualifiedName,
+                typeof(long).AssemblyQualifiedName,
+                typeof(float).AssemblyQualifiedName,
+                typeof(double).AssemblyQualifiedName,
+                typeof(bool).AssemblyQualifiedName
+            } ); 
+        
+        public bool CanParse(string name)
+        {
+            return parsers.ContainsKey(name) || BUILTIN_NAMES.Contains(name);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/Configuration/ConfigurationBuilderImpl.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/Configuration/ConfigurationBuilderImpl.cs b/lang/cs/Source/TANG/Tang/Implementations/Configuration/ConfigurationBuilderImpl.cs
new file mode 100644
index 0000000..cd2aa30
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/Configuration/ConfigurationBuilderImpl.cs
@@ -0,0 +1,364 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Org.Apache.Reef.Utilities.Logging;
+using Org.Apache.Reef.Tang.Exceptions;
+using Org.Apache.Reef.Tang.Interface;
+using Org.Apache.Reef.Tang.Types;
+using Org.Apache.Reef.Tang.Util;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+    public class ConfigurationBuilderImpl : IConfigurationBuilder
+    {
+        public IClassHierarchy ClassHierarchy;
+
+        public readonly IDictionary<IClassNode, IClassNode> BoundImpls = new MonotonicTreeMap<IClassNode, IClassNode>();
+        public readonly IDictionary<IClassNode, IClassNode> BoundConstructors = new MonotonicTreeMap<IClassNode, IClassNode>();
+        public readonly IDictionary<INamedParameterNode, String> NamedParameters = new MonotonicTreeMap<INamedParameterNode, String>();
+        public readonly IDictionary<IClassNode, IConstructorDef> LegacyConstructors = new MonotonicTreeMap<IClassNode, IConstructorDef>();
+        public readonly MonotonicMultiMap<INamedParameterNode, object> BoundSetEntries = new MonotonicMultiMap<INamedParameterNode, object>();
+        public readonly IDictionary<INamedParameterNode, IList<object>> BoundLists = new MonotonicTreeMap<INamedParameterNode, IList<object>>();
+
+        public readonly static string INIT = "<init>";
+
+        private static readonly Logger LOGGER = Logger.GetLogger(typeof(ConfigurationBuilderImpl));
+
+        protected ConfigurationBuilderImpl() 
+        {
+            this.ClassHierarchy = TangFactory.GetTang().GetDefaultClassHierarchy();
+        }
+
+        public ConfigurationBuilderImpl(IClassHierarchy classHierarchy)
+        {
+            this.ClassHierarchy = classHierarchy;
+        }
+
+        protected ConfigurationBuilderImpl(string[] assemblies, IConfiguration[] confs, Type[] parsers)
+        {
+            this.ClassHierarchy = TangFactory.GetTang().GetDefaultClassHierarchy(assemblies, parsers);
+            foreach (IConfiguration tc in confs) 
+            {
+                AddConfiguration(((ConfigurationImpl) tc));
+            }
+        }
+
+        public ConfigurationBuilderImpl(ConfigurationBuilderImpl t) 
+        {
+            this.ClassHierarchy = t.GetClassHierarchy();
+            try {
+                AddConfiguration(t.GetClassHierarchy(), t);
+            } 
+            catch (BindException e) 
+            {
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Caught(e, Level.Error, LOGGER);
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Could not copy builder", e), LOGGER); 
+            }
+        }
+
+        protected ConfigurationBuilderImpl(string[] assemblies) : this(assemblies, new IConfiguration[0], new Type[0])
+        {
+        }
+
+        protected ConfigurationBuilderImpl(IConfiguration[] confs) : this(new string[0], confs, new Type[0])
+        {
+        }
+
+        public void AddConfiguration(IConfiguration conf)
+        {
+            AddConfiguration(conf.GetClassHierarchy(), ((ConfigurationImpl)conf).Builder);
+        }
+
+        private void AddConfiguration(IClassHierarchy ns, ConfigurationBuilderImpl builder)
+        {
+            this.ClassHierarchy = this.ClassHierarchy.Merge(ns);
+            
+            if((ClassHierarchy is ClassHierarchyImpl || builder.ClassHierarchy is ClassHierarchyImpl)) 
+            {
+                if((ClassHierarchy is ClassHierarchyImpl && builder.ClassHierarchy is ClassHierarchyImpl)) 
+                {
+                    ((ClassHierarchyImpl) ClassHierarchy).Parameterparser.MergeIn(((ClassHierarchyImpl) builder.ClassHierarchy).Parameterparser);
+                } 
+                else 
+                {
+                    Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(new ArgumentException("Attempt to merge Java and non-Java class hierarchy!  Not supported."), LOGGER);
+                }
+            }
+
+            foreach (IClassNode cn in builder.BoundImpls.Keys) 
+            {
+                IClassNode n = null;
+                builder.BoundImpls.TryGetValue(cn, out n);
+                if (n != null)
+                {
+                    Bind(cn.GetFullName(), n.GetFullName());
+                }
+            }
+
+            foreach (IClassNode cn in builder.BoundConstructors.Keys) 
+            {
+                IClassNode n = null;
+                builder.BoundConstructors.TryGetValue(cn, out n);
+                if (n != null)
+                {
+                    Bind(cn.GetFullName(), n.GetFullName());
+                }
+            }
+
+            // The namedParameters set contains the strings that can be used to
+            // instantiate new
+            // named parameter instances. Create new ones where we can.
+            foreach (INamedParameterNode np in builder.NamedParameters.Keys) 
+            {
+                string v = null;
+                builder.NamedParameters.TryGetValue(np, out v);
+                Bind(np.GetFullName(), v);
+            }
+    
+            foreach (IClassNode cn in builder.LegacyConstructors.Keys) 
+            {
+                IConstructorDef cd = null;
+                builder.LegacyConstructors.TryGetValue(cn, out cd);
+                RegisterLegacyConstructor(cn, cd.GetArgs());  
+            }
+
+            foreach (KeyValuePair<INamedParameterNode, object> e in builder.BoundSetEntries) 
+            {
+              String name = ((INamedParameterNode)e.Key).GetFullName();
+              if(e.Value is INode) 
+              {
+                    BindSetEntry(name, (INode)e.Value);
+              } 
+              else if (e.Value is string) 
+              {
+                    BindSetEntry(name, (string)e.Value);
+              } else {
+                var ex = new IllegalStateException(string.Format(CultureInfo.CurrentCulture, "The value {0} set to the named parameter {1} is illegel.", e.Value, name));
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+              }
+            }
+
+            foreach (var p in builder.BoundLists)
+            {
+                BoundLists.Add(p.Key, p.Value);
+            }
+        }
+
+        public IClassHierarchy GetClassHierarchy()
+        {
+            return this.ClassHierarchy;
+        }
+
+        public void RegisterLegacyConstructor(IClassNode cn, IList<IClassNode> args)
+        {
+            LegacyConstructors.Add(cn, cn.GetConstructorDef(args));
+        }
+
+        public void RegisterLegacyConstructor(string s, IList<string> args)
+        {
+            IClassNode cn = (IClassNode) this.ClassHierarchy.GetNode(s);
+            IList<IClassNode> cnArgs = new List<IClassNode>();
+            for (int i = 0; i < args.Count; i++)
+            {
+                cnArgs.Add((IClassNode)ClassHierarchy.GetNode(args[i]));
+            }
+            RegisterLegacyConstructor(cn, cnArgs);
+        }
+
+        public void RegisterLegacyConstructor(IClassNode c, IList<IConstructorArg> args)
+        {
+            string[] cn = new string[args.Count];
+
+            for (int i = 0; i < args.Count; i++)
+            {
+                cn[i] = args[i].Gettype();
+            }
+            RegisterLegacyConstructor(c.GetFullName(), cn);
+        }
+
+        public IConfiguration Build()
+        {
+            return new ConfigurationImpl(new ConfigurationBuilderImpl(this));
+        }
+
+        public void Bind(string key, string value)
+        {
+            INode n = this.ClassHierarchy.GetNode(key);
+            if (n is INamedParameterNode)
+            {
+                BindParameter((INamedParameterNode)n, value);
+            }
+            else if (n is IClassNode)
+            {
+                INode m = this.ClassHierarchy.GetNode(value);
+                Bind((IClassNode)n, (IClassNode)m);
+            }
+            else
+            {
+                var ex = new IllegalStateException(string.Format("getNode() returned {0} which is neither a ClassNode nor a NamedParameterNode", n));
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+            }
+        }
+
+        public void Bind(Types.INode key, Types.INode value)
+        {
+            if (key is INamedParameterNode)
+            {
+                BindParameter((INamedParameterNode)key, value.GetFullName());
+            }
+            else if (key is IClassNode)
+            {
+                IClassNode k = (IClassNode)key;
+                if (value is IClassNode)
+                {
+                    IClassNode val = (IClassNode)value;
+                    if (val.IsExternalConstructor() && !k.IsExternalConstructor())
+                    {
+                        BindConstructor(k, (IClassNode) val);
+                    }
+                    else
+                    {
+                        BindImplementation(k, (IClassNode)val);
+                    }
+                }
+            }
+        }
+
+        public void BindParameter(INamedParameterNode name, String value)
+        {
+            /* Parse and discard value; this is just for type checking, skip for now*/
+            if (this.ClassHierarchy is ICsClassHierarchy) 
+            {
+                ((ICsClassHierarchy)ClassHierarchy).Parse(name, value);
+            }
+
+            if(name.IsSet()) 
+            {
+                BindSetEntry((INamedParameterNode)name, value);
+            } 
+            else 
+            {
+                NamedParameters.Add(name, value);
+            }
+        }
+
+        public void BindImplementation(IClassNode n, IClassNode m)
+        {
+            if (this.ClassHierarchy.IsImplementation(n, m))
+            {
+                BoundImpls.Add(n, m);
+            }
+            else
+            {
+                var ex = new ArgumentException(string.Format("Class {0} does not extend {1}.", m, n));
+                Org.Apache.Reef.Utilities.Diagnostics.Exceptions.Throw(ex, LOGGER);
+            }
+        }
+
+        public void BindSetEntry(String iface, String impl)
+        {
+            BoundSetEntries.Add((INamedParameterNode)this.ClassHierarchy.GetNode(iface), impl);
+        }
+
+        public void BindSetEntry(String iface, INode impl)
+        {
+            BoundSetEntries.Add((INamedParameterNode)ClassHierarchy.GetNode(iface), impl);
+        }
+
+        public void BindSetEntry(INamedParameterNode iface, String impl)
+        {
+            BoundSetEntries.Add(iface, impl);
+        }
+
+        public void BindSetEntry(INamedParameterNode iface, INode impl)
+        {
+            BoundSetEntries.Add(iface, impl);
+        }
+
+        public void BindList(INamedParameterNode iface, IList<INode> impl)
+        {
+            IList<object> l = new List<object>();
+            foreach (var n in impl)
+            {
+                l.Add((object)n);
+            }
+            BoundLists.Add(iface, l);
+        }
+
+        public void BindList(INamedParameterNode iface, IList<string> impl)
+        {
+            IList<object> l = new List<object>();
+            foreach (var n in impl)
+            {
+                l.Add((object)n);
+            }
+            BoundLists.Add(iface, l);
+        }
+
+        public void BindList(string iface, IList<INode> impl)
+        {
+            BindList((INamedParameterNode)ClassHierarchy.GetNode(iface), impl);            
+        }
+
+        public void BindList(string iface, IList<string> impl)
+        {
+            BindList((INamedParameterNode)ClassHierarchy.GetNode(iface), impl);
+        }
+
+        public void BindConstructor(Types.IClassNode k, Types.IClassNode v)
+        {
+            BoundConstructors.Add(k, v);
+        }
+
+        public string ClassPrettyDefaultString(string longName)
+        {
+            INamedParameterNode param = (INamedParameterNode) this.ClassHierarchy.GetNode(longName);
+            return param.GetSimpleArgName() + "=" + Join(",", param.GetDefaultInstanceAsStrings());
+        }
+
+        private String Join(string sep, string[] s)
+        {
+            if (s.Length == 0)
+            {
+                return null;
+            }
+            else
+            {
+                StringBuilder sb = new StringBuilder(s[0]);
+                for (int i = 1; i < s.Length; i++)
+                {
+                    sb.Append(sep);
+                    sb.Append(s[i]);
+                }
+                return sb.ToString();
+            }
+        }
+
+        public string ClassPrettyDescriptionString(string fullName)
+        {
+            INamedParameterNode param = (INamedParameterNode) this.ClassHierarchy.GetNode(fullName);
+            return param.GetDocumentation() + "\n" + param.GetFullName();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/2ae282de/lang/cs/Source/TANG/Tang/Implementations/Configuration/ConfigurationImpl.cs
----------------------------------------------------------------------
diff --git a/lang/cs/Source/TANG/Tang/Implementations/Configuration/ConfigurationImpl.cs b/lang/cs/Source/TANG/Tang/Implementations/Configuration/ConfigurationImpl.cs
new file mode 100644
index 0000000..17739e8
--- /dev/null
+++ b/lang/cs/Source/TANG/Tang/Implementations/Configuration/ConfigurationImpl.cs
@@ -0,0 +1,122 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+using System;
+using System.Collections.Generic;
+using Org.Apache.Reef.Tang.Interface;
+using Org.Apache.Reef.Tang.Types;
+
+namespace Org.Apache.Reef.Tang.Implementations
+{
+    public class ConfigurationImpl : IConfiguration
+    {
+        public readonly ConfigurationBuilderImpl Builder;
+
+        public ConfigurationImpl(ConfigurationBuilderImpl builder)
+        {
+            Builder = builder;
+        }
+
+        public IClassHierarchy GetClassHierarchy()
+        {
+            return Builder.ClassHierarchy;
+        }
+
+        public IConfigurationBuilder newBuilder()
+        {
+            return ((ConfigurationImpl)Builder.Build()).Builder;
+        }
+           
+        public ICollection<IClassNode> GetBoundImplementations()
+        {
+            return Builder.BoundImpls.Keys;
+        }
+
+        public IClassNode GetBoundImplementation(IClassNode cn)
+        {
+            IClassNode v;
+
+            Builder.BoundImpls.TryGetValue(cn, out v);
+
+            return v;
+        }
+
+        public ICollection<IClassNode> GetBoundConstructors()
+        {
+            return Builder.BoundConstructors.Keys;
+        }
+
+        public IClassNode GetBoundConstructor(IClassNode cn)
+        {
+            IClassNode v;
+
+            Builder.BoundConstructors.TryGetValue(cn, out v);
+
+            return v;
+        }
+
+        public ICollection<INamedParameterNode> GetNamedParameters()
+        {
+            return Builder.NamedParameters.Keys;
+        }
+
+        public string GetNamedParameter(INamedParameterNode np)
+        {
+            string v = null;
+            Builder.NamedParameters.TryGetValue(np, out v);
+
+            return v;
+        }
+
+        public IConstructorDef GetLegacyConstructor(IClassNode cn)
+        {
+            IConstructorDef v;
+
+            Builder.LegacyConstructors.TryGetValue(cn, out v);
+
+            return v;
+        }
+
+        public ICollection<IClassNode> GetLegacyConstructors()
+        {
+            return Builder.LegacyConstructors.Keys;
+        }
+
+        public ISet<Object> GetBoundSet(INamedParameterNode np) 
+        {
+            return Builder.BoundSetEntries.GetValuesForKey(np);
+        }
+
+        public IEnumerator<KeyValuePair<INamedParameterNode, object>> GetBoundSets() 
+        {
+            return Builder.BoundSetEntries.GetEnumerator();
+        }
+
+        public IDictionary<INamedParameterNode, IList<object>> GetBoundList()
+        {
+            return Builder.BoundLists;
+        }
+
+        public IList<object> GetBoundList(INamedParameterNode np)
+        {
+            IList<object> list;
+            Builder.BoundLists.TryGetValue(np, out list);
+            return list;
+        }
+    }
+}
\ No newline at end of file