context: // **********************************************************************
  //
  // Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
  //
  // This copy of Ice is licensed to you under the terms described in the
  // ICE_LICENSE file included in this distribution.
  //
  // **********************************************************************
  
  namespace Ice
  {
      using System.Collections;
      using System.Collections.Generic;
      using System.Threading;
  
      //
      // The base class for all ImplicitContext implementations
      //
      public abstract class ImplicitContextI : ImplicitContext
      {
          public static ImplicitContextI create(string kind)
          {
              if(kind.Equals("None") || kind.Length == 0)
              {
                  return null;
              }
              else if(kind.Equals("Shared"))
              {
                  return new SharedImplicitContext();
              }
              else if(kind.Equals("PerThread"))
              {
                  return new PerThreadImplicitContext();
              }
              else
              {
                  throw new Ice.InitializationException(
                      "'" + kind + "' is not a valid value for Ice.ImplicitContext"); 
              }
          }
          
          public abstract Dictionary<string, string> getContext();
          public abstract void setContext(Dictionary<string, string> newContext);
          public abstract bool containsKey(string key);    
          public abstract string get(string key);
          public abstract string put(string key, string value);
          public abstract string remove(string key);
  
          abstract public void write(Dictionary<string, string> prxContext,
                                     IceInternal.BasicStream os);
          abstract internal Dictionary<string, string> combine(Dictionary<string, string> prxContext);
      }
          
          
      internal class SharedImplicitContext : ImplicitContextI
      {
          public override Dictionary<string, string> getContext()
          {
              lock(this)
              {
                  return new Dictionary<string, string>(_context);
              }
          }
              
          public override void setContext(Dictionary<string, string> context)
          {
              lock(this)
              {
                  if(context != null && context.Count != 0)
                  {
                      _context = new Dictionary<string, string>(context);
                  }
                  else
                  {
                      _context.Clear();
                  }
              }
          }
              
          public override bool containsKey(string key)
          {
              lock(this)
              {
                  if(key == null)
                  {
                      key = "";
                  }
                  
                  return _context.ContainsKey(key);
              }
          }
  
          public override string get(string key)
          {
              lock(this)
              {
                  if(key == null)
                  {
                      key = "";
                  }
                  
                  string val = _context[key];
                  if(val == null)
                  {
                      val = "";
                  }
                  return val;
              }
          }
              
              
          public override string put(string key, string value)
          {
              lock(this)
              {
                  if(key == null)
                  {
                      key = "";
                  }
                  if(value == null)
                  {
                      value = "";
                  }
  
                  string oldVal;
                  _context.TryGetValue(key, out oldVal);
                  if(oldVal == null)
                  {
                      oldVal = "";
                  }
                  _context[key] = value;
                  
                  return oldVal;
              }
          }
              
          public override string remove(string key)
          {
              lock(this)
              {
                  if(key == null)
                  {
                      key = "";
                  }
  
                  string val = _context[key];
  
                  if(val == null)
                  {
                      val = "";
                  }
                  else
                  {
                      _context.Remove(key);
                  }
  
                  return val;
              }
          }
              
          public override void write(Dictionary<string, string> prxContext, IceInternal.BasicStream os)
          {
              if(prxContext.Count == 0)
              {
                  lock(this)
                  {
                      ContextHelper.write(os, _context);
                  }
              }
              else 
              {
                  Dictionary<string, string> ctx = null;
                  lock(this)
                  {
                      ctx = _context.Count == 0 ? prxContext :combine(prxContext); 
                  }
                  ContextHelper.write(os, ctx);
              }
          }
  
          internal override Dictionary<string, string> combine(Dictionary<string, string> prxContext)
          {
              lock(this)
              {
                  Dictionary<string, string> combined = new Dictionary<string, string>(prxContext);
                  foreach(KeyValuePair<string, string> e in _context)
                  {
                      try
                      {
                          combined.Add(e.Key, e.Value);
                      }
                      catch(System.ArgumentException)
                      {
                          // Ignore.
                      }
                  }
                  return combined;
              }
          }
  
          private Dictionary<string, string> _context = new Dictionary<string, string>();
      }
  
      internal class PerThreadImplicitContext : ImplicitContextI
      {
          public override Dictionary<string, string> getContext()
          {
  
gt:             Dictionary<string, string> threadContext = null;