/** Add a symbol to our scope */
  void add(Definition def) {
    // Check to see if we already have a definition
    Definition oldDef = (Definition) elements.get(def.getName());

    // If so, we'll create a MultiDef to hold them
    if (oldDef != null) {
      // If the symbol there so far was not a MultiDef
      if (!(oldDef instanceof MultiDef)) {
        // remove the old definition
        elements.remove(oldDef);

        // create a new MultiDef
        MultiDef newMulti = new MultiDef(def.getName(), oldDef);

        // add the old symbol to the MultiDef
        newMulti.addDef(oldDef);
        oldDef = newMulti;

        // add the MultiDef back into the scope
        elements.put(def.getName(), oldDef);
      }

      // We now have a multidef, so add the new symbol to it
      ((MultiDef) oldDef).addDef(def);
    }

    // Otherwise, just add the new symbol to the scope
    else {
      elements.put(def.getName(), def);
      def.setParentScope(this);
    }
  }
 private static RaiseException templateError(
     ThreadContext ctx, String message, HashAdapter definition) {
   Definition d = new Definition(definition, null);
   String codec = d.getCodec(ctx).asJavaString();
   String name = d.getName().orNull();
   return Errors.newASN1Error(
       ctx.getRuntime(), "Error while processing(" + codec + "|" + name + ") " + message);
 }
 private void walkBindingNode(
     final Compiler.Context context, final AST node, final Definition message) {
   List<AST> children = node.getChildNodes();
   final String identifier = getString(children.get(0));
   final Binding binding = message.createLanguageBinding(identifier);
   for (int i = 1; i < children.size(); i += 2) {
     final String key = getString(children.get(i));
     final String value = getString(children.get(i + 1));
     final Binding.Data prev = binding.getData(key);
     if (prev != null) {
       context.error(
           node.getCodePosition(),
           identifier
               + " language binding for "
               + message.getName()
               + " already defined for '"
               + key
               + "'");
       context.warning(prev.getCodePosition(), "this was the location of the previous definition");
     }
     binding.setData(key, value, node.getCodePosition());
   }
 }