/**
   * An xpath expression may target a "client property" mapping (in xml land, an xml attribute
   * rather than a xml element).
   *
   * @throws Exception
   */
  @Test
  public void testPropertyNameWithXlinkAttribute() throws Exception {
    final String XMMLNS = "http://www.opengis.net/xmml";
    final Name typeName = new NameImpl(XMMLNS, "Borehole");

    AppSchemaDataAccess complexDs = (AppSchemaDataAccess) mappingDataStore;

    mapping = complexDs.getMappingByElement(typeName);

    NamespaceSupport namespaces = new NamespaceSupport();
    namespaces.declarePrefix("gml", GML.NAMESPACE);
    namespaces.declarePrefix("xmml", XMMLNS);
    namespaces.declarePrefix("xlink", XLINK.NAMESPACE);

    FilterFactory2 ff = new FilterFactoryImplNamespaceAware(namespaces);
    String xpathExpression = "sa:shape/geo:LineByVector/geo:origin/@xlink:href";
    PropertyName propNameExpression = ff.property(xpathExpression);

    visitor = new UnmappingFilterVisitor(mapping);

    List /* <Expression> */ unrolled = (List) propNameExpression.accept(visitor, null);
    assertNotNull(unrolled);
    assertEquals(1, unrolled.size());
    assertTrue(unrolled.get(0) instanceof Expression);
  }
  /**
   * There might be multiple mappings per propery name, like <code>gml:name[1] = att1</code>, <code>
   * gml:name2 = strConcat(att2, att3)</code>, <code>gml:name[3] = "sampleValue</code>.
   *
   * <p>In the BoreHole test mapping used here, the following mappings exist for gml:name:
   *
   * <ul>
   *   <li>gml:name[1] = strConcat( strConcat(QS, strConcat("/", RT)), strConcat(strConcat("/",
   *       NUMB), strConcat("/", BSUFF)) )
   *   <li>gml:name[2] = BGS_ID
   *   <li>gml:name[3] = NAME
   *   <li>gml:name[4] = ORIGINAL_N
   * </ul>
   *
   * This means the "unrolled" filter for <code>gml:name = "SWADLINCOTE"</code> should be <code>
   * strConcat( strConcat(QS, ...) = "SWADLINCOTE"
   *          OR BGS_ID = "SWADLINCOTE"
   *          OR NAME = "SWADLINCOTE"
   *          OR ORIGINAL_N = "SWADLINCOTE"</code>
   *
   * <p>
   *
   * @throws Exception
   */
  @Test
  public void testCompareFilterMultipleMappingsPerPropertyName() throws Exception {
    final String XMMLNS = "http://www.opengis.net/xmml";
    final Name typeName = new NameImpl(XMMLNS, "Borehole");

    AppSchemaDataAccess complexDs = (AppSchemaDataAccess) mappingDataStore;
    mapping = complexDs.getMappingByElement(typeName);

    NamespaceSupport namespaces = new NamespaceSupport();
    namespaces.declarePrefix("gml", GML.NAMESPACE);
    namespaces.declarePrefix("xmml", XMMLNS);

    FilterFactory2 ff = new FilterFactoryImplNamespaceAware(namespaces);
    PropertyIsEqualTo complexFilter = ff.equals(ff.property("gml:name"), ff.literal("SWADLINCOTE"));

    visitor = new UnmappingFilterVisitor(mapping);

    Filter unrolled = (Filter) complexFilter.accept(visitor, null);
    assertNotNull(unrolled);
    assertNotSame(complexFilter, unrolled);

    assertTrue(unrolled.getClass().getName(), unrolled instanceof org.opengis.filter.Or);

    Or oredFilter = (Or) unrolled;
    List children = oredFilter.getChildren();
    assertEquals(4, children.size());

    assertTrue(children.get(0) instanceof PropertyIsEqualTo);
    assertTrue(children.get(1) instanceof PropertyIsEqualTo);
    assertTrue(children.get(2) instanceof PropertyIsEqualTo);
    assertTrue(children.get(3) instanceof PropertyIsEqualTo);

    PropertyIsEqualTo filter1 = (PropertyIsEqualTo) children.get(0);
    PropertyIsEqualTo filter2 = (PropertyIsEqualTo) children.get(1);
    PropertyIsEqualTo filter3 = (PropertyIsEqualTo) children.get(2);
    PropertyIsEqualTo filter4 = (PropertyIsEqualTo) children.get(3);

    assertTrue(filter1.getExpression1() instanceof Function);
    assertTrue(filter2.getExpression1() instanceof PropertyName);
    assertTrue(filter3.getExpression1() instanceof PropertyName);
    assertTrue(filter4.getExpression1() instanceof PropertyName);

    assertTrue(filter1.getExpression2() instanceof Literal);
    assertTrue(filter2.getExpression2() instanceof Literal);
    assertTrue(filter3.getExpression2() instanceof Literal);
    assertTrue(filter4.getExpression2() instanceof Literal);

    assertEquals("BGS_ID", ((PropertyName) filter2.getExpression1()).getPropertyName());
    assertEquals("NAME", ((PropertyName) filter3.getExpression1()).getPropertyName());
    assertEquals("ORIGINAL_N", ((PropertyName) filter4.getExpression1()).getPropertyName());
  }