class JndiUtils {
    /**
     * Syntax that will work with jmx ObjectNames (i.e. will escape '.' and
     * will add treat ',' and '=' specially.
     */
    private static final Properties COMPOUND_NAME_SYNTAX = new Properties();
    static {
        COMPOUND_NAME_SYNTAX.put("jndi.syntax.direction", "left_to_right");
        COMPOUND_NAME_SYNTAX.put("jndi.syntax.separator", "+");
        COMPOUND_NAME_SYNTAX.put("jndi.syntax.ignorecase", "false");
        COMPOUND_NAME_SYNTAX.put("jndi.syntax.escape", "\\");
        COMPOUND_NAME_SYNTAX.put("jndi.syntax.beginquote", "'");
        COMPOUND_NAME_SYNTAX.put("jndi.syntax.trimblanks", "true");
        COMPOUND_NAME_SYNTAX.put("jndi.syntax.separator.ava", ",");
        COMPOUND_NAME_SYNTAX.put("jndi.syntax.separator.typeval", "=");
    }
    
    public static CompoundName getCompoundName(final String name)
    throws InvalidNameException {
        return new CompoundName(name, COMPOUND_NAME_SYNTAX);
    }
    
    /**
     * Return name to use as jndi name.
     * Used to do a subset of the ObjectName fields but not just
     * let all through so its easy to just use the jndi name to 
     * find mbean.
     * @param on ObjectName instance to work with.
     * @return Returns a compound name to use as jndi key.
     * @throws NullPointerException
     * @throws InvalidNameException
     */
    public static CompoundName getCompoundName(final ObjectName on)
    throws NullPointerException,
    InvalidNameException {
        return getCompoundName(on.getCanonicalKeyPropertyListString());
    }
    
    /**
     * @param on ObjectName instance to work with.
     * @return A simple reference based on passed <code>on</code>
     */
    public static Reference getReference(final ObjectName on) {<FILL_FUNCTION_BODY>}
    
    /**
     * Get subcontext.  Only looks down one level.
     * @param subContext Name of subcontext to return.
     * @return Sub context.
     * @throws NamingException 
     */
    public static Context getSubContext(final String subContext)
    throws NamingException {
        return getSubContext(getCompoundName(subContext));
    }
    
    /**
     * Get subcontext.  Only looks down one level.
     * @param subContext Name of subcontext to return.
     * @return Sub context.
     * @throws NamingException 
     */
    public static Context getSubContext(final CompoundName subContext)
    throws NamingException {
        Context context = new InitialContext();
        try {
            context = (Context)context.lookup(subContext);
        } catch (NameNotFoundException e) {
            context = context.createSubcontext(subContext); 
        }
        return context;
    }
    
    /**
     * 
     * @param context A subcontext named for the <code>on.getDomain()</code>
     * (Assumption is that caller already setup this subcontext).
     * @param on The ObjectName we're to base our bind name on.
     * @return Returns key we used binding this ObjectName.
     * @throws NamingException
     * @throws NullPointerException
     */
    public static CompoundName bindObjectName(Context context,
            final ObjectName on)
    throws NamingException, NullPointerException {
        // I can't call getNameInNamespace in tomcat. Complains about
        // unsupported operation -- that I can't get absolute name.
        // Therefore just skip this test below -- at least for now.
        // Check that passed context has the passed ObjectNames' name.
        //
//        String name = getCompoundName(context.getNameInNamespace()).toString();
//        if (!name.equals(on.getDomain())) {
//            throw new NamingException("The current context is " + name +
//                " but domain is " + on.getDomain() + " (Was expecting " +
//                "them to be the same).");
//        }
        CompoundName key = getCompoundName(on);
        context.rebind(key, getReference(on));
        return key;
    }
    
    public static CompoundName unbindObjectName(final Context context,
            final ObjectName on)
    throws NullPointerException, NamingException {
        CompoundName key = getCompoundName(on);
        context.unbind(key);
        return key;
    }


    /**
     * Testing code.
     * @param args Command line arguments.
     * @throws NullPointerException 
     * @throws MalformedObjectNameException 
     * @throws NamingException 
     * @throws InvalidNameException 
     */
    public static void main(String[] args)
    throws MalformedObjectNameException, NullPointerException,
    InvalidNameException, NamingException {
        final ObjectName on = new ObjectName("org.archive.crawler:" +
                "type=Service,name=Heritrix00,host=debord.archive.org");
        Context c = getSubContext(getCompoundName(on.getDomain()));
        CompoundName key = bindObjectName(c, on);
        Reference r = (Reference)c.lookup(key);
        for (Enumeration<RefAddr> e = r.getAll(); e.hasMoreElements();) {
            System.out.println(e.nextElement());
        }
        unbindObjectName(c, on);
    }
}

       Reference r = new Reference(String.class.getName());
       Hashtable<String,String> ht = on.getKeyPropertyList();
       r.add(new StringRefAddr("host", (String)ht.get("host")));
       r.add(new StringRefAddr("name", (String)ht.get("name")));
       // Put in a value to serve as a unique 'key'.
       r.add(new StringRefAddr("key",
               on.getCanonicalKeyPropertyListString()));
       return r;
    
<no_super_class>