public static Object convertKey(String rawKey,
                                 TypeSpec<?> keyType,
                                 Map<String, CompoundKey.TypeInfo> keyParts,
                                 ComplexKeySpec<?, ?> complexKeyType,
                                 ProtocolVersion version)
  {
    Class<?> keyBindingClass = keyType.getType();
    Object result;

    if (TyperefInfo.class.isAssignableFrom(keyType.getType()))
    {
      TyperefDataSchema schema = (TyperefDataSchema)keyType.getSchema();
      if (!schema.getDereferencedDataSchema().isPrimitive())
      {
        throw new IllegalArgumentException("Typeref must reference a primitive type when used as a key type.");
      }

      // Coerce the raw key string to the referenced primitive type.
      DataSchema.Type dereferencedType = schema.getDereferencedType();
      Class<?> primitiveClass = DataSchemaUtil.dataSchemaTypeToPrimitiveDataSchemaClass(dereferencedType);
      result = ValueConverter.coerceString(rawKey, primitiveClass);

      // Identify the binding class for the typeref.
      keyBindingClass = CustomTypeUtil.getJavaCustomTypeClassFromSchema(schema);
      if(keyBindingClass == null)
      {
        keyBindingClass = primitiveClass;
      }
    }
    else if (CompoundKey.class.isAssignableFrom(keyType.getType()))
    {
      DataMap keyDataMap;
      if (version.compareTo(AllProtocolVersions.RESTLI_PROTOCOL_2_0_0.getProtocolVersion()) >= 0)
      {
        try
        {
          keyDataMap = (DataMap) URIElementParser.parse(rawKey);
        }
        catch (PathSegment.PathSegmentSyntaxException e)
        {
          throw new IllegalStateException(rawKey + " is not a valid value for the resource key", e);
        }
      }
      else
      {
        keyDataMap = parseKey(rawKey);
      }

      result = CompoundKey.fromValues(keyDataMap, keyParts);
    }
    else if (ComplexResourceKey.class.isAssignableFrom(keyType.getType()))
    {
      try
      {
        ComplexResourceKey<RecordTemplate, RecordTemplate> complexResourceKey =
                ComplexResourceKey.parseString(rawKey, complexKeyType, version);
        result = QueryParamsDataMap.fixUpComplexKeySingletonArray(complexResourceKey);
      }
      catch (PathSegment.PathSegmentSyntaxException e)
      {
        throw new IllegalStateException(rawKey + " is not a valid value for the resource key", e);
      }
    }
    else
    {
      try
      {
        result = ValueConverter.coerceString(rawKey, keyType.getType());
      }
      catch (IllegalArgumentException e)
      {
        throw new IllegalStateException(rawKey + " is not a valid value for resource key type " + keyType.getType().getName(), e);
      }
    }

    return DataTemplateUtil.coerceOutput(result, keyBindingClass);
  }
@Test
  public void testConvertTyperefKey()
  {
    Long longKey = (Long) ResponseUtils.convertKey("1",
                                                   TypeSpec.forClassMaybeNull(MyLongRef.class),
                                                   null,
                                                   null,
                                                   AllProtocolVersions.BASELINE_PROTOCOL_VERSION);
    Assert.assertEquals(longKey, Long.valueOf(1L));
  }